2 Layout using CodeMirror
6 getInnerWidth: function() {
7 return this.getSize().x -
8 this.getStyle('padding-left').toInt() -
9 this.getStyle('padding-right').toInt() -
10 this.getStyle('border-left-width').toInt() -
11 this.getStyle('border-right-width').toInt();
13 getInnerHeight: function() {
14 return this.getSize().y -
15 this.getStyle('padding-top').toInt() -
16 this.getStyle('padding-bottom').toInt() -
17 this.getStyle('border-top-width').toInt() -
18 this.getStyle('border-bottom-width').toInt();
27 }; // these mods will be checked
31 editors_order: ['html', 'css', 'js'],
32 reservedKeys: [ // list of [modifier,keycode,callbackname]
33 ['ctrlKey', 13, 'run'], ['control', 13, 'run'], // c+ret+run
34 ['ctrlKey', 38, 'switchPrev'], // c+upArrow
35 ['ctrlKey', 40, 'switchNext'], // c+dnArrow
36 ['ctrlKey+shiftKey', 13, 'loadDraft'], ['control+shift', 13, 'loadDraft'],
37 ['ctrlKey+shiftKey', 38, 'toggleSidebar'], ['control+shift', 38, 'toggleSidebar'],
38 ['ctrlKey+shiftKey', 76, 'showShortcutDialog'], ['control+shift', 76, 'showShortcutDialog'],
39 ['ctrlKey', 83, 'saveAndReload'], ['control', 83, 'saveAndReload'],
40 ['ctrlKey', 75, 'launchTowtruck'], ['control', 75, 'launchTowtruck']
42 // ['ctrlKey', f, 'searchBox'], ['control', f, 'searchBox']
44 isMobile: (navigator.userAgent.match(/(iPhone|iPod|iPad)/) ||
45 navigator.userAgent.match(/BlackBerry/) ||
46 navigator.userAgent.match(/Android/)),
48 // instantiate sidebar
49 // this.sidebar = new Sidebar({
53 'resize': this.resize.bind(this),
54 'keydown': function(keyEvent) {
55 // console.log(keyEvent)
56 if (this.isReservedKey(false, keyEvent)) {
57 this.routeReservedKey(keyEvent);
61 // this.sidebar.addEvents({
62 // 'accordion_resized': this.resize.bind(this)
65 var result = document.id('result');
66 $$('.window_label').setStyle('opacity', 0.8);
68 result.getElement('.window_label').setStyle('opacity', 0.3);
69 this.result = result.getElement('iframe');
73 this.resize.bind(this).delay(20);
74 // change behaviour for IE
75 if (!Browser.Engine.trident4) {
76 this.createDragInstances();
78 this.createErrorTooltips();
80 this.fireEvent('ready');
82 this.refreshEditors();
85 createErrorTooltips: function(){
86 var tooltip = Element('span', {
87 'class': 'CodeMirror-error-tooltip'
88 }).inject(document.body);
89 document.id('content').addEvents({
90 'mouseover:relay(.CodeMirror-line-error)': function(el){
92 html: this.get('data-title'),
105 'mouseout:relay(.CodeMirror-line-error)': function(){
118 routeReservedKey: function(keyEvent) {
119 this.reservedKeys.each(function(keyDef){
120 if (this.matchKey(keyEvent, keyDef)) {
121 mooshell[keyDef.getLast()].bind(mooshell).call();
126 matchKey: function(keyEvent, keyDef) {
127 if (!keyEvent) return false;
128 var key = keyEvent.keyCode || keyEvent.code;
129 // check if the right key is pressed
130 if (!keyDef.contains(key)) return false;
131 // check for the modifications
133 if (keyDef.length > 1) {
135 keyDef[0].split('+').each(function(mod) {
139 $each(keyMods, function(value, mod) {
140 if (!mods[mod]) mods[mod] = false;
142 // check all possibilities
143 $each(mods, function(required, mod) {
144 if (!!keyEvent[mod] != required) pass = false;
150 isReservedKey: function(keyCode, keyEvent) {
151 return (this.reservedKeys.some(function(keyDef) {
152 return this.matchKey(keyEvent, keyDef);
156 findLayoutElements: function() {
157 // look up some elements, and cache the findings
158 this.content = document.id('content');
159 this.columns = this.content.getChildren('.column');
160 this.windows = this.content.getElements('.window');
161 this.shims = this.content.getElements('.column .shim');
163 'vertical': this.content.getElementById('handler_vertical'),
164 'left': this.columns[0].getElement('.handler_horizontal'),
165 'right': this.columns[1].getElement('.handler_horizontal')
169 registerEditor: function(editor) {
170 this.editors[editor.options.name] = editor;
174 decodeEditors: function() {
175 this.editors.each(function(ed) {
180 updateFromMirror: function() {
181 this.editors.each(function(ed) {
182 ed.updateFromMirror();
186 cleanMirrors: function() {
187 this.editors.each(function(ed) {
192 createDragInstances: function() {
193 var onDrag_horizontal = function(h) {
194 var windows = h.getParent().getElements('.window');
195 var top = (h.getPosition(this.content).y + h.getHeight() / 2) / this.content.getHeight() * 100;
196 windows[0].setStyle('height', top + '%');
197 windows[1].setStyle('height', 100 - top + '%');
198 this.refreshEditors();
201 var onDrag_vertical = function(h) {
202 var left = (h.getPosition(this.content).x + h.getWidth() / 2) / this.content.getWidth() * 100;
203 this.columns[0].setStyle('width', left + '%');
204 this.columns[1].setStyle('width', 100 - left + '%');
207 this.handlers.each(function(h) {
208 var isHorizontal = h.hasClass('handler_horizontal');
209 h.dragInstance = new Drag(h, {
210 'modifiers': isHorizontal ? {'x': null, 'y': 'top'} : {'x': 'left', 'y': null},
212 'x': [100, this.content.getWidth() - 100],
213 'y': [100, this.content.getHeight() - 100]
215 'onBeforeStart': function() { this.shims.show(); }.bind(this),
216 'onDrag': isHorizontal ? onDrag_horizontal : onDrag_vertical,
217 'onCancel': function() { this.shims.hide(); }.bind(this),
218 'onComplete': function() { this.shims.hide(); }.bind(this)
222 // Save window sizes to cookie onUnload.
223 window.addEvent('unload', function() {
228 this.columns.each(function(col, i) {
229 var width = col.getStyle('width');
230 sizes.w[i] = width.contains('%') ? width : null;
232 this.windows.each(function(win, i) {
233 var height = win.getStyle('height');
234 sizes.h[i] = height.contains('%') ? height : null;
236 Cookie.write('window_sizes', JSON.encode(sizes), {'domain': location.host});
239 // Read window sizes from cookie.
240 this.setWindowSizes();
243 setWindowSizes: function(sizes) {
244 // sizes === undefined --> read from cookie
245 // sizes == null/false --> reset sizes + delete cookie
246 // sizes == true --> use sizes
247 if (typeof sizes === 'undefined') {
248 sizes = Cookie.read('window_sizes');
250 sizes = JSON.decode(sizes);
254 if ($type(sizes.w) === 'array') {
255 sizes.w.each(function(width, i) {
256 this.columns[i].setStyle('width', width);
259 if ($type(sizes.h) == 'array') {
260 sizes.h.each(function(height, i) {
261 this.windows[i].setStyle('height', height);
265 this.columns.setStyle('width', null);
266 this.windows.setStyle('height', null);
267 Cookie.dispose('window_sizes', {'domain': location.host});
272 resize: function(e) {
274 this.findLayoutElements();
277 var win_size = window.getSize();
278 var av_height = win_size.y -
279 this.columns[0].getPosition().y +
280 this.windows[0].getStyle('top').toInt() +
281 this.windows[1].getStyle('bottom').toInt();
283 this.content.setStyle('height', av_height);
285 // set handler positions
286 this.handlers.vertical.setStyle('left', this.windows[0].getCoordinates(this.content).right);
287 this.handlers.left.setStyle('top', this.windows[0].getCoordinates(this.content).bottom);
288 this.handlers.right.setStyle('top', this.windows[2].getCoordinates(this.content).bottom);
290 this.fireEvent('resize');
293 refreshEditors: function(){
294 Object.each(this.editors, function(editorInstance){
295 editorInstance.editor.refresh();
300 // add events to Layout object
301 $extend(Layout, new Events());