moved Tabs and Sidebar into the editor app

can almost remove FlightDeck.Editor
This commit is contained in:
Sean McArthur 2011-10-20 17:59:15 -05:00
Родитель 3b7f5be91e
Коммит 88834a723d
8 изменённых файлов: 1259 добавлений и 149 удалений

Просмотреть файл

@ -11,12 +11,6 @@
<script src="/media/lib/ace/ace-uncompressed.js"></script>
<script src="/media/lib/tree.js"></script>
{% if settings.DEBUG %}
<script src="/media/lib/shipyard/scripts/require.js?1" data-main="/media/jetpack/js/editor/"></script>
{% else %}
<script src="/media/jetpack/js/editor-min.js"></script>
{% endif %}
<script src="/media/jetpack/js/FlightDeck.Editor.js"></script>
<script src="/media/lib/ace/ace.js"></script>
<script src="/media/lib/ace/mode-javascript.js"></script>
@ -35,6 +29,12 @@
};
});
</script>
{% if settings.DEBUG %}
<script src="/media/lib/shipyard/scripts/require.js" data-main="/media/jetpack/js/editor/"></script>
{% else %}
<script src="/media/jetpack/js/editor-min.js"></script>
{% endif %}
{% endblock %}
@ -47,7 +47,10 @@
{# initialize package view #}
{% block app_domready %}
fd.item = new Package(require('editor/settings'));
var editor = require('editor');
fd.item = editor.controller;
editor.sidebar.buildTree();
{% endblock %}

Просмотреть файл

@ -6,68 +6,6 @@ FlightDeck = Class.refactor(FlightDeck,{
initialize: function(options) {
this.setOptions(options);
this.sidebar = new (require('editor').Sidebar)();
var tabs = this.tabs = new (require('editor/views/Tabs').TabBar)('editor-tabs', {
arrows: false,
onTabDown: function(tab) {
if (!tab.hasClass('selected')) {
tab.retrieve('tab:instance').file.onSelect();
}
},
onCloseDown: function(tabClose) {
var tabEl = tabClose.getParent('.tab');
var nextTab = tabEl.hasClass('selected') ?
tabEl.getPrevious('.tab.') || tabEl.getNext('.tab') :
$(tabs).getElement('.tab.selected');
if(nextTab) {
var tab = tabEl.retrieve('tab:instance'),
that = this,
file = tab.file;
function closeTab() {
tab.destroy();
that.fireEvent('tabDown', nextTab);
}
if(file.changed) {
fd.showQuestion({
title: 'Lose unsaved changes?',
message: 'The tab "'+file.getShortName()+'" that you are trying to close has unsaved changes.',
buttons: [
{
'type': 'reset',
'text': 'Cancel',
'class': 'close'
},
{
'type': 'submit',
'text': 'Close Tab',
'id': 'close_tab_btn',
'default': true,
'irreversible': true,
'callback': function() {
closeTab();
//do this after editor changes instances, cause editor
//dumps content when it changes
setTimeout(function() {
file.content = file.original_content;
file.setChanged(false);
fd.edited--;
if(!fd.edited) {
fd.fireEvent('reset');
}
}, 1);
}
}
]
});
} else {
closeTab();
}
}
}
});
this.previous(options);
this.edited = 0;

Просмотреть файл

@ -5,7 +5,6 @@
/*
* Javascript Package/PackageRevision representation
*/
var FDEditor = require('editor/views/FDEditor.Ace');
var Package = new Class({
Implements: [Options, Events],
@ -61,8 +60,8 @@ var Package = new Class({
$('version_name').set('value', this.options.version_name);
}
// initiate the sidebar
//fd.sidebar.options.editable = !this.options.readonly;
//fd.sidebar.buildTree();
//editor.sidebar.options.editable = !this.options.readonly;
//editor.sidebar.buildTree();
this.instantiate_modules();
this.instantiate_attachments();
this.instantiate_folders();
@ -356,7 +355,7 @@ var File = new Class({
if (!first) {
first = true;
mod.switchTo();
fd.sidebar.setSelectedFile(mod);
editor.sidebar.setSelectedFile(mod);
}
});
if (!first) {
@ -383,7 +382,7 @@ var File = new Class({
},
makeTab: function() {
var tab = this.tab = new (require('editor/views/Tabs').Tab)(fd.tabs, {
var tab = this.tab = new (require('editor/views/Tabs').Tab)(editor.tabs.tabs, {
title: this.getShortName()
});
this.addEvent('change', function() {
@ -399,7 +398,7 @@ var File = new Class({
if(!this.tab) {
this.makeTab();
}
fd.tabs.setSelected(this.tab);
editor.tabs.tabs.setSelected(this.tab);
},
setChanged: function(isChanged) {
@ -437,7 +436,7 @@ var Library = new Class({
},
append: function() {
fd.sidebar.addPlugin(this);
editor.sidebar.addPlugin(this);
},
onSelect: function() {
@ -578,7 +577,7 @@ var Attachment = new Class({
},
append: function() {
fd.sidebar.addData(this);
editor.sidebar.addData(this);
},
reassign: function(options) {
@ -670,7 +669,7 @@ var Module = new Class({
},
append: function() {
fd.sidebar.addLib(this);
editor.sidebar.addLib(this);
},
loadContent: function() {
@ -734,9 +733,9 @@ var Folder = new Class({
append: function() {
if (this.options.root_dir == Folder.ROOT_DIR_LIB) {
fd.sidebar.addLib(this);
editor.sidebar.addLib(this);
} else if (this.options.root_dir == Folder.ROOT_DIR_DATA) {
fd.sidebar.addData(this);
editor.sidebar.addData(this);
}
},
@ -1078,8 +1077,8 @@ Package.Edit = new Class({
filename = filename.getFileName();
}
var attachmentEl = fd.sidebar.getBranchFromPath(newName, 'data');
var spinnerEl = attachmentEl || $(fd.sidebar.trees.data);
var attachmentEl = editor.sidebar.getBranchFromPath(newName, 'data');
var spinnerEl = attachmentEl || $(editor.sidebar.trees.data);
new Request.JSON({
url: that.options.rename_attachment_url,
@ -1128,7 +1127,7 @@ Package.Edit = new Class({
new Request.JSON({
url: self.options.remove_attachment_url,
useSpinner: true,
spinnerTarget: fd.sidebar.getBranchFromFile(attachment),
spinnerTarget: editor.sidebar.getBranchFromFile(attachment),
spinnerOptions: {
img: {
'class': 'spinner-img spinner-16'
@ -1178,7 +1177,7 @@ Package.Edit = new Class({
renameModule: function(oldName, newName) {
newName = newName.replace(/\..*$/, '');
var el = fd.sidebar.getBranchFromPath(newName+'.js', 'lib');
var el = editor.sidebar.getBranchFromPath(newName+'.js', 'lib');
new Request.JSON({
url: this.options.rename_module_url,
useSpinner: true,
@ -1212,7 +1211,7 @@ Package.Edit = new Class({
},
removeModule: function(module) {
var el = fd.sidebar.getBranchFromFile(module);
var el = editor.sidebar.getBranchFromFile(module);
new Request.JSON({
url: this.options.remove_module_url,
useSpinner: true,
@ -1233,7 +1232,7 @@ Package.Edit = new Class({
},
removeAttachments: function(path) {
var el = fd.sidebar.getBranchFromPath(path, 'data');
var el = editor.sidebar.getBranchFromPath(path, 'data');
new Request.JSON({
url: this.options.remove_folder_url,
data: {
@ -1255,15 +1254,15 @@ Package.Edit = new Class({
this.attachments[uid].destroy();
}, this);
response.removed_dirs.forEach(function(name) {
fd.sidebar.removeFile(name, 'd')
editor.sidebar.removeFile(name, 'd')
}, this);
fd.sidebar.removeFile(response.foldername, 'd')
editor.sidebar.removeFile(response.foldername, 'd')
}.bind(this)
}).send();
},
removeModules: function(path) {
var el = fd.sidebar.getBranchFromPath(path, 'lib');
var el = editor.sidebar.getBranchFromPath(path, 'lib');
new Request.JSON({
url: this.options.remove_module_url,
data: {filename: path+'/'},
@ -1282,7 +1281,7 @@ Package.Edit = new Class({
this.modules[filename].destroy();
}, this);
response.removed_dirs.forEach(function(name) {
fd.sidebar.removeFile(name, 'l')
editor.sidebar.removeFile(name, 'l')
}, this);
}.bind(this)
@ -1326,7 +1325,7 @@ Package.Edit = new Class({
root_dir: folder.options.root_dir
},
useSpinner: true,
spinnerTarget: fd.sidebar.getBranchFromFile(folder),
spinnerTarget: editor.sidebar.getBranchFromFile(folder),
spinnerOptions: {
img: {
'class': 'spinner-img spinner-16'
@ -1410,7 +1409,7 @@ Package.Edit = new Class({
var lib = that.libraries[latest_revision.id_number];
if (!lib) return;
lib.storeNewVersion(latest_revision);
fd.sidebar.setPluginUpdate(lib);
editor.sidebar.setPluginUpdate(lib);
});
}
}).send();
@ -1439,7 +1438,7 @@ Package.Edit = new Class({
url: this.options.remove_library_url,
data: {'id_number': lib.options.id_number},
useSpinner: true,
spinnerTarget: fd.sidebar.getBranchFromFile(lib),
spinnerTarget: editor.sidebar.getBranchFromFile(lib),
spinnerOptions: {
img: {
'class': 'spinner-img spinner-16'
@ -1711,7 +1710,7 @@ Package.Edit = new Class({
description: 'Open the New Attachment prompt.',
handler: function(e) {
e.preventDefault();
fd.sidebar.promptAttachment();
editor.sidebar.promptAttachment();
}
},
'new module': {
@ -1719,7 +1718,7 @@ Package.Edit = new Class({
description: 'Open the New Module prompt.',
handler: function(e) {
e.preventDefault();
fd.sidebar.promptNewFile();
editor.sidebar.promptNewFile();
}
},
'focus tree / editor': {
@ -1729,9 +1728,9 @@ Package.Edit = new Class({
e.preventDefault();
if(that._focused) {
that.blur();
fd.sidebar.focus();
editor.sidebar.focus();
} else {
//fd.sidebar.blur();
//editor.sidebar.blur();
that.focus();
}
}
@ -1744,11 +1743,11 @@ Package.Edit = new Class({
}
}
})
this.keyboard.manage(fd.sidebar.keyboard);
this.keyboard.manage(editor.sidebar.keyboard);
this.keyboard.activate();
fd.sidebar.keyboard.deactivate();
editor.sidebar.keyboard.deactivate();
this.addEvent('focus', function() {
fd.sidebar.blur();
editor.sidebar.blur();
});
},
@ -1769,7 +1768,7 @@ Package.Edit = new Class({
shortcuts.push('<strong>Editor</strong>');
this.keyboard.getShortcuts().forEach(buildLines);
shortcuts.push('<strong>Tree</strong>');
fd.sidebar.keyboard.getShortcuts().forEach(buildLines);
editor.sidebar.keyboard.getShortcuts().forEach(buildLines);
this._shortcutsModal = fd.displayModal('<h3>Keyboard Shortcuts</h3>'
+'<div class="UI_Modal_Section"><p>'

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,78 @@
/* depends on `fd`
*/
var Class = require('shipyard/class/Class'),
Events = require('shipyard/class/Events'),
Options = require('shipyard/class/Options'),
tabs = require('../views/Tabs');
module.exports = new Class({
initialize: function() {
this.tabs = new tabs.TabBar('editor-tabs', {
arrows: false,
onTabDown: function(tab) {
if (!tab.hasClass('selected')) {
tab.retrieve('tab:instance').file.onSelect();
}
},
onCloseDown: function(tabClose) {
var tabEl = tabClose.getParent('.tab');
var nextTab = tabEl.hasClass('selected') ?
tabEl.getPrevious('.tab.') || tabEl.getNext('.tab') :
$(tabs).getElement('.tab.selected');
if(nextTab) {
var tab = tabEl.retrieve('tab:instance'),
that = this,
file = tab.file;
function closeTab() {
tab.destroy();
that.fireEvent('tabDown', nextTab);
}
if(file.changed) {
fd.showQuestion({
title: 'Lose unsaved changes?',
message: 'The tab "'+file.getShortName()+'" that you are trying to close has unsaved changes.',
buttons: [
{
'type': 'reset',
'text': 'Cancel',
'class': 'close'
},
{
'type': 'submit',
'text': 'Close Tab',
'id': 'close_tab_btn',
'default': true,
'irreversible': true,
'callback': function() {
closeTab();
//do this after editor changes instances, cause editor
//dumps content when it changes
setTimeout(function() {
file.content = file.original_content;
file.setChanged(false);
fd.edited--;
if(!fd.edited) {
fd.fireEvent('reset');
}
}, 1);
}
}
]
});
} else {
closeTab();
}
}
}
});
}
});

Просмотреть файл

@ -1,20 +1,23 @@
// requiring these now so they are included in the bundle
var settings = require('editor/settings');
var PackageController = require('./controllers/PackageController');
var Package = require('./models/Package');
var TabsController = require('./controllers/TabsController');
var Ace = require('./views/FDEditor.Ace');
var Sidebar = require('./views/Sidebar');
// TODO: remove this once no files outside 'editor' app need the editor
window.editor = exports;
// requiring these now so they are included in the bundle
//TODO: eventually, this file would connect Models and Views with some
// controllers
var Ace = require('./views/FDEditor.Ace');
var editor = exports = module.exports = new Ace('editor-wrapper');
exports.Sidebar = require('./views/Sidebar');
exports.Tabs = require('./views/Tabs');
console.log('editor/index');
var Package = require('./models/Package');
fd.sidebar.options.editable = settings.editable;
fd.sidebar.buildTree();
exports.tabs = new TabsController();
exports.sidebar = new Sidebar({ editable: !settings.readonly });
exports.ace = new Ace('editor-wrapper');
var p = exports.item = new Package(settings);
exports.controller = new PackageController(p, settings);
var p = exports.package = new Package(settings);
exports.controller = new PackageController(p, settings, exports.ace, exports.tabs, exports.sidebar);

Просмотреть файл

@ -0,0 +1,28 @@
var Class = require('shipyard/class/Class'),
Model = require('shipyard/model/Model'),
fields = require('shipyard/model/fields'),
Syncable = require('shipyard/sync/Syncable'),
ServerSync = require('shipyard/sync/Server');
module.exports = new Class({
Extends: Model,
Implements: Syncable,
Sync: {
'default': {
driver: ServerSync,
route: '/api/0/packagerevisions'
}
},
fields: {
id: fields.NumberField(),
revision_number: fields.NumberField(),
created_at: fields.DateField()
// modules, attachments, dependencies
}
});

Просмотреть файл

@ -17,8 +17,7 @@ var BUTTONS = {
'package-copy': string.uniqueID(),
'try_in_browser': string.uniqueID(),
'download': string.uniqueID(),
'error-console': string.uniqueID(),
'package-save': string.uniqueID()
'error-console': string.uniqueID()
}
function resetDom() {
@ -30,6 +29,8 @@ function resetDom() {
body.grab(new dom.Element('input', { id: 'version_name' }));
body.grab(new dom.Element('div', { id: 'revisions_list' }));
body.grab(new dom.Element('input', { id: 'revision_message' }));
body.grab(new dom.Element('a', { id: 'package-save' }));
object.forEach(BUTTONS, function(href, id) {
var a = new dom.Element('a', { href: href });
@ -51,6 +52,7 @@ module.exports = {
'PackageController': function(it, setup) {
var addon;
var editOptions = { readonly: false };
setup('beforeEach', function() {
resetDom();
@ -64,12 +66,7 @@ module.exports = {
it('should instantiate', function(expect) {
var pc = new PackageController(addon, {
modules: [
{id: 1, filename: 'foo'},
{id: 2, filename: 'bar'}
]
});
var pc = new PackageController(addon);
expect(pc).toBeAnInstanceOf(PackageController);
expect(pc.package).toBe(addon);
});
@ -86,7 +83,7 @@ module.exports = {
});
it('should register revisions_list click', function(expect) {
var pc = new PackageController(addon, {});
var pc = new PackageController(addon);
pc.showRevisionList = new Spy;
@ -158,10 +155,65 @@ module.exports = {
});
it('should be bound to showInfo', function(expect) {
var pc = new PackageController(addon);
var pc = new PackageController(addon, { readonly: true });
pc.showInfo = new Spy;
pc.packageInfoEl.fireEvent('click', new E);
expect(pc.showInfo.getCallCount()).toBe(1);
});
// Edit Actions
it('should be bound to editInfo', function(expect) {
var pc = new PackageController(addon, editOptions);
pc.editInfo = new Spy;
pc.packageInfoEl.fireEvent('click', new E);
expect(pc.editInfo.getCallCount()).toBe(1);
});
it('should bind console_el to open console', function(expect) {
var fd = { send: new Spy };
dom.window.node.mozFlightDeck = fd;
var pc = new PackageController(addon, editOptions);
pc.console_el.fireEvent('click', new E);
expect(fd.send.getCallCount()).toBe(1);
expect(fd.send.getLastArgs()).toBeLike([{
cmd: 'toggleConsole',
contents: 'open'
}]);
delete dom.window.node.mozFlightDeck;
});
it('should bind save_el to saveAction', function(expect) {
var pc = new PackageController(addon, editOptions);
pc.saveAction = new Spy;
pc.save_el.fireEvent('click', new E);
expect(pc.saveAction.getCallCount()).toBe(1);
});
it('should create logical tab order in save popover', function(expect) {
var pc = new PackageController(addon, editOptions);
var versionFocus = new Spy,
saveFocus = new Spy;
// jury-rig the .focus() methods to trigger our event
// handlers
pc.versionEl.focus = function() { this.fireEvent('focus', new E); };
pc.save_el.focus = pc.versionEl.focus;
pc.versionEl.addEvent('focus', versionFocus);
pc.save_el.addEvent('focus', saveFocus);
pc.save_el.fireEvent('mouseenter', new E);
expect(versionFocus.getCallCount()).toBe(1);
var tab = new E;
tab.key = 'tab';
pc.revision_message_el.fireEvent('keypress', tab);
expect(saveFocus.getCallCount()).toBe(1);
});
}
}