/*
* eAmy.Offline - Amy Editor embedded for offline use.
* http://www.april-child.com/amy
*
* Published under MIT License.
* Copyright (c) 2007-2008 Petr Krontorád, April-Child.com
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*
*
* This file is auto-generated from original Fry Framework and Amy Editor sources..
*/
/*
* AC Fry - JavaScript Framework v1.0
* (c)2006 Petr Krontorad, April-Child.com
* Portions of code based on WHOA Bender Framework, (c)2002-2005 Petr Krontorad, WHOA Group.
* http://www.april-child.com. All rights reserved.
* See the license/license.txt for additional details regarding the license.
* Special thanks to Matt Groening and David X. Cohen for all the robots.
*/
/* Reserving global `fry` object */
var fry =
{
version:1.0,
__production_mode:false
};
// String prototype enhancements
String.prototype.camelize = function()
{
return this.replace( /([-_].)/g, function(){ return arguments[0].substr(1).toUpperCase();} );
}
String.prototype.decamelize = function()
{
return this.replace( /([A-Z])/g, function(){ return '-'+arguments[0].toLowerCase();} );
}
String.prototype.trim = function()
{
return this.replace(/(^\s*)|(\s*$)/g, '' );
}
String.prototype.stripLines = function()
{
return this.replace( /\n/g, '' );
}
String.prototype.stripMarkup = function()
{
return this.replace( /<(.|\n)+?>/g, '' );
}
String.prototype.replaceMarkup = function( charRep )
{
return this.replace( /(<(.|\n)+?>)/g, function()
{
var t = '';
for ( var i=0; i/g, '>' ).replace( /' ).replace( /&/g, '&' );
}
String.prototype.surround = function(t, side)
{
side = side || 3;
return (1==1&side?t:'')+this+(2==2&side?t:'');
}
String.prototype.surroundTag = function(t)
{
return '<'+t+'>'+this+''+t+'>';
}
// example of use: var pattern = '? is ?; alert(pattern.embed('Decin', 'sunny')); pattern = '@city is @weather'; alert(pattern.embed({weather:'cloudy', city:'Decin'}))
String.prototype.embed = function()
{
var t = this;
if ( 1 == arguments.length && 'object' == typeof arguments[0] )
{
// named placeholders
for ( var i in arguments[0] )
{
eval('var re=/@'+i+'/g;');
t = t.replace(re, arguments[0][i]);
}
}
else
{
// anonymous placeholders `?`
for ( var i=0; i opacity )
{
opacity = 0;
}
if ( 1 < opacity )
{
opacity = 1;
}
if ( $__tune.isIE )
{
node.style.filter = 'alpha(opacity='+(100*opacity)+')';
}
else
{
node.style.opacity = opacity;
node.style.MozOpacity = opacity;
}
},
getPageScrollPosition:function()
{
var d = document.documentElement;
if ( d && d.scrollTop)
{
return [d.scrollLeft, d.scrollTop];
}
else if (document.body)
{
return [document.body.scrollLeft, document.body.scrollTop];
}
else
{
return [0, 0];
}
}
},
event:
{
get:function(evt, type)
{
if ( $notset(evt.target) )
{
evt.target = evt.srcElement;
evt.stopPropagation = function()
{
window.event.cancelBubble = true;
};
}
evt.stop = function()
{
evt.stopPropagation();
evt.stopped = true;
}
evt.$ = $(evt.target);
if ( $notset(evt.pageX) )
{
evt.pageX = evt.clientX + document.body.scrollLeft;
evt.pageY = evt.clientY + document.body.scrollTop;
}
evt.getOffsetX = function()
{
if ( $notset(evt.offsetX) )
{
var pos = evt.$.abspos();
evt.offsetX = evt.pageX - pos.x;
evt.offsetY = evt.pageY - pos.y;
}
return evt.offsetX;
}
evt.getOffsetY = function()
{
if ( $notset(evt.offsetY) )
{
var pos = evt.$.abspos();
evt.offsetX = evt.pageX - pos.x;
evt.offsetY = evt.pageY - pos.y;
}
return evt.offsetY;
}
evt.isAnyControlKeyPressed = function()
{
return evt.metaKey||evt.ctrlKey||evt.altKey||evt.shiftKey;
}
evt.KEY_ESCAPE = 27;
evt.KEY_ENTER = 13;
evt.KEY_ARR_RIGHT = 39;
evt.KEY_ARR_LEFT = 37;
evt.KEY_ARR_UP = 38;
evt.KEY_ARR_DOWN = 40;
return evt;
},
addListener:function(node, type, listener)
{
if ( $__tune.isIE && node.attachEvent )
{
node.attachEvent('on'+type, listener);
}
else
{
node.addEventListener(type, listener, false);
}
},
removeListener:function(node, type, listener)
{
if ( node.detachEvent )
{
node.detachEvent('on'+type, listener);
node['on'+type] = null;
}
else if ( node.removeEventListener )
{
node.removeEventListener(type, listener, false);
}
}
},
behavior:
{
disablePageScroll:function()
{
if ( $notset($__tune.__prop.page_scroll) )
{
$__tune.__prop.page_scroll = [$().s().overflow, $().ga('scroll')];
}
$().s('overflow:hidden').sa('scroll', 'no');
},
enablePageScroll:function()
{
$().s('overflow:auto').sa('scroll', 'yes');
},
disableCombos:function()
{
$().g('select', function(node)
{
node.sa('__dis_combo', node.s().visibility);
$(node).v(false);
});
},
enableCombos:function()
{
$().g('select', function(node)
{
node.s({visibility:node.ga('__dis_combo') || 'visible'});
});
},
clearSelection:function()
{
try
{
if ( window.getSelection )
{
if ( $__tune.isSafari )
{
window.getSelection().collapse();
}
else
{
window.getSelection().removeAllRanges();
}
}
else
{
if ( document.selection )
{
if ( document.selection.empty )
{
document.selection.empty();
}
else
{
if ( document.selection.clear )
{
document.selection.clear();
}
}
}
}
}
catch (e) {}
},
makeBodyUnscrollable:function()
{
$().s('position:fixed').w(fry.ui.info.page.width);
}
},
ui:
{
scrollbarWidth:-1!=navigator.appVersion.indexOf('intosh')?15:17
},
selection:
{
setRange:function(el, selectionStart, selectionEnd)
{
if (el.setSelectionRange)
{
el.focus();
el.setSelectionRange(selectionStart, selectionEnd);
}
else if (el.createTextRange)
{
var range = el.createTextRange();
range.collapse(true);
range.moveEnd('character', selectionEnd);
range.moveStart('character', selectionStart);
range.select();
}
}
}
}
// some browsers masks its presence having Gecko string somewhere inside its userAgent field...
$__tune.isGecko = !$__tune.isSafari&&!$__tune.isIE&&-1!=navigator.userAgent.indexOf('ecko');
$__tune.isSafari2 = $__tune.isSafari && -1 != navigator.appVersion.indexOf('Kit/4');
$__tune.isSafari3 = $__tune.isSafari && -1 != navigator.appVersion.indexOf('Kit/5');
// Node manipulations
function ACNode(node)
{
this.$ = node;
if ( node )
{
node.setAttribute('fryis', '1');
}
}
// `$$` creates new node
ACNode.prototype.$$ = function(tagName)
{
return $$(tagName);
}
// *is* - tells whether node is a part of the active DOM tree (that is displayed on page). Node may exist only in memory before appending or after removing when references, in which case node.is() will return false.
ACNode.prototype.is = function()
{
return this.$ && null != this.$.parentNode;
}
// *i*d
ACNode.prototype.i = function(id)
{
if ( 'undefined' == typeof id )
{
return this.$.id||'';
}
this.$.id = id;
return this;
}
// class *n*ame
ACNode.prototype.n = function(n)
{
if ( 'undefined' == typeof n)
{
return this.$.className||'';
}
this.$.className = n;
return this;
}
// *e*vent listener, if called with one argument only, previously registered listeners are removed
ACNode.prototype.e = function(t, c, oneUseOnly)
{
var ser_type_id = 'fryse-'+t;
if ( !c )
{
if ( null != this.$.getAttribute(ser_type_id) )
{
var ser_listeners = this.$.getAttribute(ser_type_id).split(',');
// console.log('*E* removing listeners for %s, listeners: %s', t, ser_listeners);
for ( var i=0; i h )
{
this.$.style.fontSize = '1px';
}
return this;
}
// *s*tyle information - argument can be either "{color:'red', backgroundColor:'blue'}" or "'color:red;background-color:blue'"
ACNode.prototype.s = function(s)
{
if ( 'undefined' == typeof s )
{
return this.$.style;
}
if ( 'object' == typeof s )
{
for ( var n in s )
{
this.$.style[n] = s[n];
}
}
else if ( 'string' == typeof s )
{
if ( '' != s )
{
var styles = s.split(';');
for ( var i=0; idiv>table>tbody>tr>td>` and node at `td`
// to return second div you would call `gp('tr/tbody/table/div')` or `tr/table/div:1`, first div could be acquired using `table/div:2` etc. you can use `*` for any node.
ACNode.prototype.gp = function(q)
{
if ( 'string' == typeof q )
{
q = q.split('/');
}
var fq = [];
for ( var i=0; i to && to>=from )
{
self.clearInterval(t);
}
else
{
c(i, control);
if ( control.stopped )
{
self.clearInterval(t);
}
}
i++;
}, interval);
}
// $dotimes
// ========
// Repeats embedded code n times.
/* Usage:
$dotimes(20, function(i)
{
// your code, i is the counter parameter
})
*/
var $dotimes = function(n, c)
{
for ( var i=0; i i )
{
control.skip();
return;
}
tr.n(0==i%2 ? 'even' : 'odd');
if ( 20 < i )
{
control.stop();
}
})
*/
var $foreach = function(o, c)
{
if ( !o )
{
c = null;
return;
}
if ( 'undefined' == typeof o.length && 'function' != typeof o.__length )
{
c = null;
return;
}
var n = 'function' == typeof o.__length ? o.__length() : o.length;
var control =
{
stopped:false,
stop:function()
{
this.stopped = true;
},
skipped:false,
skip:function()
{
this.skipped = true;
},
removed:false,
remove:function(stopAfterwards)
{
this.removed = true;
this.stopped = true == stopAfterwards;
}
}
// cannot just extend Array.prototype for `item()` method due bug in IE6 iteration mechanism. Some day (>2010 :) this might get fixed and will become obsolete
for ( var i=0; i= evt.keyCode)
{
fry.keyboard.pushKey(evt.keyCode + 32, fry.keyboard.META_KEY);
evt.preventDefault();
return true;
}
}
}
fry.keyboard.initialized = true;
fry.keyboard.start();
}
fry.keyboard.start = function()
{
fry.keyboard.stopped = false;
}
fry.keyboard.stop = function()
{
fry.keyboard.stopped = true;
}
fry.keyboard.disableTextfieldsEditation = function()
{
fry.keyboard.allowTextfieldsEditation(true);
}
fry.keyboard.allowTextfieldsEditation = function(disable)
{
var lst = document.getElementsByTagName('input');
var n = lst.length;
for (var i=0; i evt.keyCode))
{
// control code
mask++;
}
if (!fry.keyboard.pushKey(code, mask))
{
return true;
}
}
evt.preventDefault();
evt.stopPropagation();
return false;
}
fry.keyboard.paste.ff_mac = function(evt)
{
fry.keyboard.last_down_evt = null;
// catching Command+C, Command+X, it's a FF.mac hack
if (evt.metaKey && ((67 == evt.keyCode && 0 == evt.charCode && 67 == evt.which) || (88 == evt.keyCode && 0 == evt.charCode && 88 == evt.which)))
{
return fry.keyboard.shared.copy(evt);
}
else
{
return 86 == evt.keyCode && 0 == evt.charCode && 86 == evt.which && evt.metaKey;
}
}
fry.keyboard.down.ff_mac = function(evt)
{
return false;
}
fry.keyboard.press.ff_mac = function(evt)
{
if (null != fry.keyboard.last_down_evt)
{
return;
}
var mask = (evt.altKey ? 2 : 0) + (evt.ctrlKey ? 4 : 0) + (evt.shiftKey ? 8 : 0) + (evt.metaKey ? 16 : 0);
if (!evt.charCode || (evt.charCode == evt.keyCode))
{
// control code
fry.keyboard.pushKey(evt.keyCode, 1 + mask);
}
else
{
if (!fry.keyboard.pushKey(evt.charCode, mask))
{
return true;
}
}
evt.preventDefault();
evt.stopPropagation();
return false;
}
fry.keyboard.paste.webkit = function(evt)
{
if ($__tune.isMac)
{
return (86 == evt.keyCode && (0 == evt.charCode || 118 == evt.charCode) && evt.metaKey);
}
else
{
return (86 == evt.keyCode && (0 == evt.charCode || 118 == evt.charCode) && evt.ctrlKey);
}
}
fry.keyboard.down.webkit = function(evt)
{
if (0 != evt.keyCode && (48 > evt.keyCode || (111 < evt.keyCode && 128 > evt.keyCode) || 60000 < evt.charCode))
{
var mask = (evt.altKey ? 2 : 0) + (evt.ctrlKey ? 4 : 0) + (evt.shiftKey ? 8 : 0) + (evt.metaKey ? 16 : 0);
if (!evt.charCode || 111 < evt.keyCode || 32 > evt.charCode || 60000 < evt.charCode)
{
// control code
fry.keyboard.pushKey(evt.keyCode, 1 + mask);
}
else
{
if (!fry.keyboard.pushKey(evt.charCode, mask))
{
return true;
}
}
evt.preventDefault();
evt.stopPropagation();
fry.keyboard.last_down_evt = null;
return false;
}
fry.keyboard.last_down_evt = evt;
return true;
}
fry.keyboard.press.webkit = function(evt)
{
if (null != fry.keyboard.last_down_evt)
{
var mask = (evt.altKey ? 2 : 0) + (evt.ctrlKey ? 4 : 0) + (evt.shiftKey ? 8 : 0) + (evt.metaKey ? 16 : 0);
var code = !evt.keyCode ? evt.charCode : evt.keyCode;
if (evt.keyCode == evt.charCode && evt.keyCode == fry.keyboard.last_down_evt.charCode && evt.keyCode > 60000)
{
code = fry.keyboard.last_down_evt.keyCode;
}
if (evt.keyCode == fry.keyboard.last_down_evt.keyCode && 48 > evt.keyCode)
{
// control code
mask++;
}
else
{
var r_mask = fry.keyboard.SHIFT_KEY + fry.keyboard.META_KEY;
if (r_mask == (mask & r_mask) && 97 <= code && 122 >= code)
{
code -= 32;
}
}
if (!fry.keyboard.pushKey(code, mask))
{
return true;
}
}
evt.preventDefault();
evt.stopPropagation();
return false;
}
fry.keyboard.paste.ie = function(evt)
{
if (evt.ctrlKey && (67 == evt.keyCode || 88 == evt.keyCode))
{
// ctrl+c, ctrl+x
return fry.keyboard.shared.copy(evt);
}
else
{
return false;
}
}
fry.keyboard.down.ie = function(evt)
{
fry.keyboard.last_down_evt = evt;
if (48 > evt.keyCode || (111 < evt.keyCode && 128 > evt.keyCode))
{
// control code for IE
var mask = 1 + (evt.altKey ? 2 : 0) + (evt.ctrlKey ? 4 : 0) + (evt.shiftKey ? 8 : 0) + (evt.metaKey ? 16 : 0);
return !fry.keyboard.pushKey(evt.keyCode, mask)
}
else
{
var code = evt.keyCode;
// disabling some other keys (A, F, N, R, S, T)
if (82 == evt.keyCode || 65 == evt.keyCode || 83 == evt.keyCode || 70 == evt.keyCode || 78 == evt.keyCode || 84 == evt.keyCode)
{
if (!evt.shiftKey)
{
code += 32;
}
var mask = (evt.altKey ? 2 : 0) + (evt.ctrlKey ? 4 : 0) + (evt.shiftKey ? 8 : 0) + (evt.metaKey ? 16 : 0);
return !fry.keyboard.pushKey(code, mask);
}
}
return true;
}
fry.keyboard.press.ie = function(evt)
{
if (null != fry.keyboard.last_down_evt)
{
var mask = (evt.altKey ? 2 : 0) + (evt.ctrlKey ? 4 : 0) + (evt.shiftKey ? 8 : 0) + (evt.metaKey ? 16 : 0);
return !fry.keyboard.pushKey(evt.keyCode, mask);
}
return false;
}
fry.keyboard.paste.opera = function(evt)
{
return 86 == evt.keyCode && 86 == evt.which && evt.ctrlKey;
}
fry.keyboard.down.opera = function(evt)
{
fry.keyboard.last_down_evt = evt;
return false;
}
fry.keyboard.press.opera = function(evt)
{
var e = fry.keyboard.last_down_evt;
var mask = (evt.altKey ? 2 : 0) + (evt.ctrlKey ? 4 : 0) + (evt.shiftKey ? 8 : 0) + (evt.metaKey ? 16 : 0);
var prev_mask = (e.altKey ? 2 : 0) + (e.ctrlKey ? 4 : 0) + (e.shiftKey ? 8 : 0) + (e.metaKey ? 16 : 0);
if ((evt.keyCode == fry.keyboard.last_down_evt.keyCode || 0 == e.keyCode) && (0 == evt.which || 48 > e.keyCode || 111 < e.keyCode))
{
mask++;
}
if (!fry.keyboard.pushKey(evt.keyCode, mask))
{
return true;
}
evt.preventDefault();
evt.stopPropagation();
return false;
}
fry.keyboard.addListener = function(listener)
{
fry.keyboard.listener = listener;
}
fry.keyboard.removeListener = function(listener)
{
fry.keyboard.listener = null;
}
fry.keyboard.pushKey = function(code, mask)
{
if (32 == code)
{
mask = mask & 65534;
}
var was_clipboard_copy = false;
var was_clipboard_cut = false;
if ($__tune.isMac)
{
was_clipboard_copy = (99 == code) && (fry.keyboard.META_KEY == (mask & fry.keyboard.META_KEY));
was_clipboard_cut = (120 == code) && (fry.keyboard.META_KEY == (mask & fry.keyboard.META_KEY));
}
else
{
was_clipboard_copy = (1 == code || 99 == code) && (fry.keyboard.CTRL_KEY == (mask & fry.keyboard.CTRL_KEY));
was_clipboard_cut = (24 == code || 120 == code) && (fry.keyboard.CTRL_KEY == (mask & fry.keyboard.CTRL_KEY));
}
if (was_clipboard_copy || was_clipboard_cut)
{
fry.keyboard.prepareClipboard();
fry.keyboard.clipboard.copiedContent = '';
var was_custom_content = false;
if (fry.keyboard.listener)
{
var content = fry.keyboard.listener(0, fry.keyboard.CONTROL_CODE | fry.keyboard.SIG_CLIPBOARD_GET);
if ('string' == typeof content)
{
was_custom_content = true;
fry.keyboard.clipboard.copiedContent = content;
}
}
if (was_custom_content)
{
fry.keyboard.clipboard.node.value = fry.keyboard.clipboard.copiedContent;
fry.keyboard.clipboard.node.select();
fry.keyboard.clipboard.node.focus();
}
fry.keyboard.pushKey(0, fry.keyboard.CONTROL_CODE | (was_clipboard_cut ? fry.keyboard.CUT : fry.keyboard.COPY));
fry.keyboard.clipboard.content = fry.keyboard.clipboard.copiedContent;
// returning false will enforce propagation
return !was_custom_content;
}
if (fry.keyboard.PASTE == (mask & fry.keyboard.PASTE))
{
fry.keyboard.clipboard.pastedContent = code;
fry.keyboard.clipboard.content = fry.keyboard.clipboard.pastedContent;
code = 0;
}
// filtering out solo-keys Ctrl, Shift, Alt that are triggered by some browsers.
if ((17 == code && 5 == (mask & 5)) || (16 == code && 9 == (mask & 9)) || (18 == code && 3 == (mask & 3)))
{
return true;
}
// filtering out Command+V on FF.mac
if (118 == code && 16 == mask)
{
return true;
}
if (fry.keyboard.listener)
{
// console.info(code);
if (13 != code && 0 != (mask & (fry.keyboard.CONTROL_CODE + fry.keyboard.META_KEY + fry.keyboard.CTRL_KEY)))
{
// some keystroke occured that we really want to know about the listener result, we have to call it immediatelly
return fry.keyboard.listener(code, mask);
}
else
{
// let's ease the pain of the browser
setTimeout('fry.keyboard.listener('+code+','+mask+')', 10);
}
}
else
{
fry.keyboard.buffer.unshift([code, mask]);
}
return true;
}
fry.keyboard.popKey = function()
{
return fry.keyboard.buffer.pop();
}
fry.keyboard.getClipboardContent = function()
{
return fry.keyboard.clipboard.content;
}
/*--------*/
var client = {conf:{fry:{backendURL:''}}};
var eamy =
{
snippets:[],
instances:[]
};
/*
* ac.Chap - Text Editing Component - Core
*/
if ( 'undefined' == typeof ac )
{
var ac = {chap:{}};
}
ac.chap =
{
state:
{
active:null
},
TOKEN_MULTIROW_COMMENT:0,
TOKEN_SINGLEROW_COMMENT:1,
TOKEN_SINGLE_QUOTED:2,
TOKEN_DOUBLE_QUOTED:3,
TOKEN_NEWROW:4,
TOKEN_WHITESPACE:5,
ROWSTATE_NONE:0,
ROWSTATE_FOLD_START:1,
ROWSTATE_FOLD_STOP:2,
ROWSTATE_FOLD_EXPAND:4,
ROWSTATE_FOLD_COLLAPSED:8,
ROWSTATE_SELECTION:16,
ROWSTATE_BOOKMARK:32,
CHUNK_KEYWORD:4,
CHUNK_NUMBER:5,
CHUNK_OPERATOR:6,
CHUNK_PARENTHESIS:7,
CHUNK_KEYWORD_CUSTOM:8,
CHUNK_FUNCTION_NAME:9,
CHUNK_LIBRARY:10,
CHUNK_LIBRARY_CUSTOM:11,
ACTION_CARET:1,
ACTION_SELECTION:2,
ACTION_INSERT:3,
ACTION_UPDATE:4,
ACTION_DELETE:5,
ACTION_CLIPBOARD:6,
ACTION_UNDO:7,
ACTION_REDO:8,
ACTION_CUSTOM:9,
ACTION_RES_REDRAWCARET:1,
ACTION_RES_REDRAWTEXT:2,
ACTION_RES_SELECTIONCHANGED:4,
ACTION_RES_SCROLLTOCARET:8,
CKEY_NONE:0,
CKEY_ALT:2,
CKEY_CTRL:4,
CKEY_SHIFT:8,
CKEY_META:16,
TRANSLOG_TYPE_INSERT:1,
TRANSLOG_TYPE_REMOVE:2,
ACTION_LISTENER_BEFORE:1,
ACTION_LISTENER_AFTER:2,
ACTION_LISTENER_BOTH:3
}
ac.chap.activeComponent = null;
ac.chap.instanceId = 1;
ac.chap.getActiveComponent = function()
{
return ac.chap.activeComponent;
}
ac.chap.setActiveComponent = function(component)
{
fry.keyboard.initialize();
if (null != ac.chap.activeComponent)
{
ac.chap.activeComponent.blur();
}
ac.chap.activeComponent = component;
if (null != component)
{
if (ac.widget)
{
ac.widget.focus(component);
}
ac.chap.activeComponent.focus();
}
else
{
if (!ac.widget)
{
fry.keyboard.stop();
}
}
}
ac.chap.route = function(type, windowId, viewIndex, pars)
{
if ( null == ac.chap.activeComponent )
{
return;
}
if ( 'undefined' == typeof ac.chap.activeComponent.views[viewIndex] )
{
return;
}
switch ( type )
{
case 'expand-folding':
{
ac.chap.activeComponent.expandFolding(pars);
}
}
}
ac.chap.caretThread = setInterval(function()
{
if (null != ac.chap.activeComponent)
{
ac.chap.activeComponent.showCaret(true, true);
}
}, 600);
$(document.documentElement).e($__tune.isSafari2?'mousedown':'click', function(evt)
{
var elem = evt.$.$;
while ( null != elem && document.documentElement != elem )
{
if ( 'true' == elem.getAttribute('chap-view') )
{
evt.stop();
return;
}
elem = elem.parentNode;
}
ac.chap.setActiveComponent(null);
});
ac.chap.keyboardListener = function(code, mask)
{
if (null == ac.chap.activeComponent)
{
return;
}
return ac.chap.activeComponent.standaloneKeyboardListener(code, mask);
}
if ('undefined' == typeof ac['widget'])
{
// chap is not a part of Fry MVC, must handle keyboardListener itself
fry.keyboard.addListener(ac.chap.keyboardListener);
}
$class('ac.chap.Window',
{
construct:function(options, userId)
{
this.instanceId = ac.chap.instanceId++;
this.ident = 'ac-chap-' + this.instanceId;
this.userId = userId | 0;
this.caret = null;
this.options = null;
this.state = null;
this.views = [];
this.activeView = null;
this.viewLayoutNodes = [];
this.char_map = [];
this.row_id_map = [];
this.syntax_map = [];
this.style_map = [];
this.row_id_sequence = 1;
this.language = null;
this.keymap = null;
this.snippets = [];
this.commands = [];
this.selection = null;
this.transaction_log = [];
this.redo_log = [];
this.setOptions(options||{});
this.setState();
},
destruct:function()
{
$delete(this.state);
$delete(this.options);
$delete(this.char_map);
$delete(this.row_id_map);
$delete(this.syntax_map);
$delete(this.style_map);
this.hide();
$delete(this.activeView);
}
});
ac.chap.Window.prototype.focus = function()
{
this.showCaret();
}
ac.chap.Window.prototype.blur = function()
{
this.hideCaret();
}
// compatibility layer with AC Fry Widget library
ac.chap.Window.prototype.onFocus = function()
{
ac.chap.setActiveComponent(this);
this.focus();
}
ac.chap.Window.prototype.onBlur = function()
{
ac.chap.setActiveComponent(null);
this.blur();
}
ac.chap.Window.prototype.onResize = function(width, height)
{
}
ac.chap.Window.prototype.onSystemClipboardCopy = function()
{
return this.getSelection();
}
ac.chap.Window.prototype.onSystemClipboardCut = function()
{
this.runAction(ac.chap.ACTION_CLIPBOARD, {cut:true});
return this.processActionResult(true, true);
}
ac.chap.Window.prototype.onSystemClipboardPaste = function(content)
{
this.runAction(ac.chap.ACTION_CLIPBOARD, {paste:true, content:content});
return this.processActionResult(true, true);
}
ac.chap.Window.prototype.hasKeyboardListenerActive = function()
{
return true;
}
ac.chap.Window.prototype.onCut = function(selection, callbackOk)
{
}
ac.chap.Window.prototype.onPaste = function(selection, wasCut)
{
}
ac.chap.Window.prototype.setOptions = function(options)
{
this.options =
{
initialCaretPosition:[0,0],
tokenizerLazyLaunch:900,
syntaxHighlightingEnabled:true,
remoteBackendURL:'',
font:{
size:11,
family: $__tune.isMac ? "Consolas, 'Bitstream Vera Sans mono', 'Courier', 'Monaco', monospaced" : "Consolas, 'Courier New', 'Courier', monospaced",
allowedSizes: [8, 9, 10, 11, 12, 13, 14, 17, 21, 24, 27, 30, 34, 38, 42]
}
};
if ( $isset(options.initial_caret_position) )
{
this.options.initialCaretPosition = [options.initial_caret_position[0], options.initial_caret_position[1]];
}
if ( $isset(options.language) )
{
this.language = $new(options.language);
}
else
{
this.language = $new(ac.chap.Language);
}
if ( $isset(options.keymap) )
{
this.keymap = $new(options.keymap);
}
else
{
this.keymap = $new(ac.chap.KeyMap);
}
if ( $isset(options.syntaxHighlightingEnabled) )
{
this.options.syntaxHighlightingEnabled = options.syntaxHighlightingEnabled;
}
if ( $isset(options.remoteBackendURL) )
{
this.options.remoteBackendURL = options.remoteBackendURL;
}
else
{
if ( client && client.conf && client.conf.fry )
{
this.options.remoteBackendURL = client.conf.fry.backendURL;
}
}
if ($isset(options.font))
{
if ($isset(options.font['size']))
{
this.options.font.size = options.font.size;
}
if ($isset(options.font['family']))
{
this.options.font.family = options.font.family;
}
}
}
ac.chap.Window.prototype.setState = function()
{
this.state =
{
lastKeyTimePressed:0,
caretPhase:1,
lastKeyCode:0,
lastControlKey:0,
lastCaretPosition:[],
tokenizerTimer:null,
scheduledTokenizerTime:0,
transactionLogStopped:false,
actionListeners:[],
actionListenersStopped:false,
caretListener:null,
commandListener:null,
transactionListener:[null,800],
passThroughKeysListener:null
}
this.caret =
{
position:[this.options.initialCaretPosition[0], this.options.initialCaretPosition[1]],
mode:1 // 1 normal, 2 overwrite
}
}
ac.chap.Window.prototype.addView = function(layoutNode, options, renderAfter)
{
var view_index = this.views.length;
this.viewLayoutNodes.push(layoutNode);
this.views.push($new(ac.chap.View, this, view_index, options||{}));
this.row_id_map[view_index] = [];
if ( 0 < view_index )
{
// console.log(view_index);
// creating duplicate
var n = this.row_id_map[0].length;
for ( var i=0; i= 0; i--)
{
if (font_size > font_sizes[i])
{
font_size = font_sizes[i];
break;
}
}
}
else
{
if (font_sizes[0] <= value && value <= font_sizes[font_sizes.length-1])
{
font_size = value;
}
}
this.options.font.size = font_size;
redraw = true;
}
else if ('font.family' == key)
{
this.options.font.family = value;
redraw = true;
}
else if ('word.wrap' == key)
{
if (this.activeView)
{
this.hideCaret();
this.activeView.options.wordWrap = value;
this.activeView.reloadOptions();
this.showCaret();
}
}
if (redraw)
{
this.hideCaret();
var num_views = this.views.length;
for (var i=0; i caret_col )
{
caret_col++;
}
else
{
if ( 'undefined' != typeof this.char_map[caret_row+1] )
{
caret_row++;
caret_col = 0;
}
}
this.setCaretPosition(caret_row, caret_col);
return ac.chap.ACTION_RES_REDRAWCARET;
}
else if ( 'up' == direction )
{
if ( 0 < caret_row )
{
var move_end = this.char_map[caret_row].length == caret_col;
if ( move_end )
{
caret_col = this.char_map[caret_row-1].length;
}
else
{
caret_col = Math.min(this.char_map[caret_row-1].length, caret_col);
}
this.setCaretPosition(caret_row-1, caret_col);
return ac.chap.ACTION_RES_REDRAWCARET;
}
}
else if ( 'down' == direction )
{
if ( 'undefined' != typeof this.char_map[caret_row+1] )
{
var move_end = this.char_map[caret_row].length == caret_col;
if ( move_end )
{
caret_col = this.char_map[caret_row+1].length;
}
else
{
caret_col = Math.min(this.char_map[caret_row+1].length, caret_col);
}
this.setCaretPosition(caret_row+1, caret_col);
return ac.chap.ACTION_RES_REDRAWCARET;
}
}
else if ( 'prev_word' == direction )
{
if ( 0 < caret_col )
{
var ch = this.char_map[caret_row].charAt(caret_col-1);
var re = this.language.wordDelimiter;
var look_for_wch = re.test(ch);
while ( 0 != caret_col )
{
ch = this.char_map[caret_row].charAt(caret_col-1);
if ( look_for_wch != re.test(ch) )
{
break;
}
caret_col--;
}
}
else
{
if ( 0 < caret_row )
{
caret_row--;
caret_col = this.char_map[caret_row].length;
}
}
this.setCaretPosition(caret_row, caret_col);
return ac.chap.ACTION_RES_REDRAWCARET;
}
else if ( 'next_word' == direction )
{
if ( this.char_map[caret_row].length > caret_col )
{
var ch = this.char_map[caret_row].charAt(caret_col);
var re = this.language.wordDelimiter;
var look_for_wch = re.test(ch);
while ( this.char_map[caret_row].length > caret_col )
{
ch = this.char_map[caret_row].charAt(caret_col);
if ( look_for_wch != re.test(ch) )
{
break;
}
caret_col++;
}
}
else
{
if ( 'undefined' != typeof this.char_map[caret_row+1] )
{
caret_row++;
caret_col = 0;
}
}
this.setCaretPosition(caret_row, caret_col);
return ac.chap.ACTION_RES_REDRAWCARET;
}
else if ( 'prev_regexp' == direction )
{
if ( 0 < caret_col )
{
var row = this.char_map[caret_row].substring(0, caret_col);
var re = new RegExp(params['re'].replace('|', '\\'));
var matches = re.exec(row);
if (0 == matches.length)
{
console.warning('Invalid RE definition for `prev_regexp\' direction in ACTION_CARET.move action in keymap.');
caret_col--;
}
else
{
caret_col -= matches[0].length + 1;
}
}
else
{
if ( 0 < caret_row )
{
caret_row--;
caret_col = this.char_map[caret_row].length;
}
}
this.setCaretPosition(caret_row, caret_col);
return ac.chap.ACTION_RES_REDRAWCARET;
}
else if ( 'next_regexp' == direction )
{
if ( this.char_map[caret_row].length > caret_col )
{
var row = this.char_map[caret_row].substr(caret_col + 1);
var re = new RegExp(params['re'].replace('|', '\\'));
var matches = re.exec(row);
if (0 == matches.length)
{
console.warning('Invalid RE definition for `next_regexp\' direction in ACTION_CARET.move action in keymap.');
caret_col++;
}
else
{
caret_col += matches[0].length + 1;
}
}
else
{
if ( 'undefined' != typeof this.char_map[caret_row+1] )
{
caret_row++;
caret_col = 0;
}
}
this.setCaretPosition(caret_row, caret_col);
return ac.chap.ACTION_RES_REDRAWCARET;
}
else if ( 'row_start' == direction )
{
if ( 0 < caret_col )
{
caret_col = 0;
this.setCaretPosition(caret_row, caret_col);
return ac.chap.ACTION_RES_REDRAWCARET;
}
}
else if ( 'row_end' == direction )
{
if ( this.char_map[caret_row].length > caret_col )
{
caret_col = this.char_map[caret_row].length;
this.setCaretPosition(caret_row, caret_col);
return ac.chap.ACTION_RES_REDRAWCARET;
}
}
else if ( 'page_up' == direction )
{
if (this.activeView)
{
var row = caret_row - this.activeView.numRows;
if (0 > row)
{
row = 0;
}
this.setCaretPosition(row, 0 != caret_col ? this.char_map[row].length : 0);
return ac.chap.ACTION_RES_REDRAWCARET;
}
return 0;
}
else if ( 'page_down' == direction )
{
if (this.activeView)
{
var row = caret_row + this.activeView.numRows;
if (this.char_map.length <= row)
{
row = this.char_map.length-1;
}
this.setCaretPosition(row, 0 != caret_col ? this.char_map[row].length : 0);
return ac.chap.ACTION_RES_REDRAWCARET;
}
return 0;
}
else if ( 'doc_start' == direction )
{
this.setCaretPosition(0,0);
return ac.chap.ACTION_RES_REDRAWCARET;
}
else if ( 'doc_end' == direction )
{
var last_index = this.char_map.length-1
this.setCaretPosition(last_index, this.char_map[last_index].length-1);
return ac.chap.ACTION_RES_REDRAWCARET;
}
}
else if ( $isset(params.moveBy) )
{
var offset = params.moveBy;
if ( 'column' == offset )
{
//move by params.value columns, newlines are counted as column, params.value may be negative indication caret moving to the left
if ( 0 < params.value )
{
var range_source = (this.char_map[caret_row].substr(caret_col)+'\n'+this.char_map.slice(caret_row+1).join('\n')).substr(0, params.value);
range_source = range_source.split('\n');
caret_row += range_source.length-1;
caret_col = range_source[range_source.length-1].length + (1==range_source.length ? caret_col : 0);
}
else
{
var range_source = (this.char_map.slice(0, caret_row).join('\n')+'\n'+this.char_map[caret_row].substr(0, caret_col));
range_source = range_source.substr(range_source.length+params.value);
range_source = range_source.split('\n');
caret_row -= (range_source.length-1);
caret_col = (1==range_source.length ? caret_col : this.char_map[caret_row].length) - range_source[0].length;
}
this.setCaretPosition(caret_row, caret_col);
return ac.chap.ACTION_RES_REDRAWCARET;
}
else if ( 'row' == offset )
{
// move by params.value rows
}
else if ( 'page' == offset )
{
// move by params.value pages
}
}
else if ( $isset(params.moveTo) )
{
// move to params.moveTo[0], params.moveTo[1]
this.setCaretPosition(params.moveTo[0], params.moveTo[1]);
return ac.chap.ACTION_RES_REDRAWCARET;
}
};break;
case ac.chap.ACTION_SELECTION:
{
if ( $isset(params.remove) )
{
var changed = this.removeSelection();
return ac.chap.ACTION_RES_REDRAWCARET | (changed ? ac.chap.ACTION_RES_REDRAWTEXT : 0);
}
else if ( $isset(params.add) )
{
this.addSelection([caret_row, caret_col], this.state.lastCaretPosition);
this.renderSelection();
return ac.chap.ACTION_RES_REDRAWCARET | ac.chap.ACTION_RES_SELECTIONCHANGED;
}
else if ( $isset(params.all) )
{
$__tune.behavior.clearSelection();
this.addAllSelection();
this.renderSelection();
return ac.chap.ACTION_RES_REDRAWCARET | ac.chap.ACTION_RES_SELECTIONCHANGED;
}
};break;
case ac.chap.ACTION_INSERT:
{
var str = null;
if ( $isset(params.row) )
{
var ins_content = '\n';
caret_col = 0;
// if ( 0 < caret_row )
// {
// // indenting by previous row
// var t = this.char_map[caret_row];
// var n = t.length;
// var re = this.language.indentIgnoreMarker;
// while ( caret_col width )
{
// will go before [row,column]
source = this.char_map.slice(0, row).join('\n')+'\n'+this.char_map[row].substr(0, column);
return source.substr(source.length+width);
}
else
{
// will go after [row,column]
source = this.char_map.slice(row).join('\n').substr(column);
return source.substr(0, width);
}
}
ac.chap.Window.prototype.getWordAt = function(row, column, numWords)
{
// if numWords <0 returns words before otherwise after position. if omitted, default value is -1 that is word before caret
// also, if more than one word is required, returns array of words as result
row = $getdef(row, this.caret.position[0]);
column = $getdef(column, this.caret.position[1]);
numWords = $getdef(numWords, -1);
var words = [];
var re = this.language.wordDelimiter;
var required_words = numWords;
var direction_after = 0 < numWords;
var next_word = true;
required_words = Math.abs(-numWords);
if ( !direction_after )
{
column--;
if ( -1 == column )
{
row--;
if ( -1 == row )
{
return words;
}
column = this.char_map[row].length-1;
}
}
while (true)
{
var ch = this.char_map[row].charAt(column)
if ( re.test(ch) )
{
if ( next_word )
{
words.push('');
next_word = false;
}
// word character found
if ( direction_after )
{
words[words.length-1] += ch;
}
else
{
words[words.length-1] = ch + words[words.length-1];
}
}
else
{
if ( required_words == words.length )
{
break;
}
next_word = true;
}
column += (direction_after ? 1 : -1);
if ( 0 > column )
{
row--;
if ( -1 == row )
{
break;
}
next_word = true;
column = this.char_map[row].length-1;
}
else if ( this.char_map[row].length <= column )
{
row++;
if ( this.char_map.length == row )
{
break;
}
next_word = true;
column = 0;
}
}
if ( 1 == required_words )
{
return words[0] ? words[0] : false;
}
return words;
}
ac.chap.Window.prototype.getLineAt = function(row)
{
return this.char_map[row];
}
ac.chap.Window.prototype.getText = function()
{
return this.char_map.join('\n');
}
ac.chap.Window.prototype.getNumRows = function()
{
return this.char_map.length;
}
ac.chap.Window.prototype.getSyntaxHighlightingSource = function()
{
if (null != this.activeView)
{
return this.activeView.getSyntaxHighlightingSource();
}
return 'ni';
}
ac.chap.Window.prototype.getCaretAbsolutePosition = function()
{
if ( null != this.activeView )
{
var pos = this.activeView.getRenderedCharPosition(this.caret.position[0], this.caret.position[1]);
if ( null != pos )
{
var root_pos = this.activeView.nodeScrollArea.abspos();
return [pos[0]+root_pos.x+this.activeView.options.colWidth, pos[1]+root_pos.y+this.activeView.options.rowHeight];
}
}
return null;
}
ac.chap.Window.prototype.stopTransactionLog = function()
{
this.state.transactionLogStopped = true;
}
ac.chap.Window.prototype.startTransactionLog = function()
{
this.state.transactionLogStopped = false;
}
ac.chap.Window.prototype.addAllSelection = function()
{
var num_rows = this.char_map.length;
var num_views = this.views.length;
for ( var i=0; i offset_x - mid_char_w )
{
col_index = i;
break;
}
else if ( w - mid_char_w < offset_x && (dim[0] % w + 2*mid_char_w >= offset_x))
{
// last char
col_index = i+1;
break;
}
}
i++;
}
// console.log('%s, %s', row_index, col_index);
if ( i == num_chars )
{
col_index = i;
}
// console.log('CHANGE CARET to: %s', col_index);
this.hideCaret();
if ( evt.shiftKey )
{
this.addSelection([row_index, col_index], this.state.lastCaretPosition);
this.renderText();
}
else
{
this.setCaretPosition(row_index, col_index);
this.state.caretPhase = 1;
view.showCaret();
this.state.lastCaretPosition = [this.caret.position[0], this.caret.position[1]];
if ( this.removeSelection() )
{
this.renderText();
}
}
ac.chap.setActiveComponent(this);
}
ac.chap.Window.prototype.foldingize = function()
{
var startRowIndex = 0;
var source_rows = this.char_map.slice(startRowIndex);
// creating folding info
var n = source_rows.length;
var foldings = [];
var foldings_index = -1;
for ( var i=0; i ixs[i][1] )
{
found_marker_index = i;
lowest = ixs[i][1];
}
}
}
if ( -1 == found_marker_index )
{
break;
}
var start_index = ixs[found_marker_index][1];
var skipped_source = source.substr(0, start_index);
var num_skipped_rows = skipped_source.split('\n').length;
cursor.row += num_skipped_rows - 1;
cursor.col = (1 == num_skipped_rows ? col_offset : 0) + skipped_source.length - ('\n'+skipped_source).lastIndexOf('\n');
if ( 'undefined' == typeof syntax_map[cursor.row] )
{
syntax_map[cursor.row] = [];
}
var start_marker_len = ixs[found_marker_index][2].length;
var end_marker_len = ixs[found_marker_index][3].length;
source = source.substr(start_index+start_marker_len);
var token_type = ixs[found_marker_index][0];
var end_index = source.indexOf(ixs[found_marker_index][3]);
var sub_source = source;
var end_index_offset = 0;
var except = false;
while ( 0 < end_index && '' != ixs[found_marker_index][4] && ixs[found_marker_index][4] == sub_source.charAt(end_index-end_marker_len) )
{
except = true;
end_index_offset += end_index + end_marker_len;
sub_source = sub_source.substr(end_index+end_marker_len);
end_index = sub_source.indexOf(ixs[found_marker_index][3]);
}
if ( except && -1 != end_index )
{
end_index += end_index_offset;
}
if ( -1 == end_index )
{
syntax_map[cursor.row].push([token_type, cursor.col, -1, '']);
fillRowTokens(token_type, cursor.row+1, -1);
break;
}
else
{
var block_source = source.substr(0, end_index);
var num_block_rows = '\n' == ixs[found_marker_index][3] ? 1 : block_source.split('\n').length;
var cursor_col_end = block_source.length - ('\n'+block_source).lastIndexOf('\n');
syntax_map[cursor.row].push([token_type, cursor.col, 1 == num_block_rows ? (cursor.col+end_index+start_marker_len+end_marker_len) : -1, ixs[found_marker_index][2]]);
fillRowTokens(token_type, cursor.row+1, cursor.row+num_block_rows-1);
if ( 1 == num_block_rows )
{
col_offset = cursor.col + end_index + start_marker_len + end_marker_len;
if ( '\n' == ixs[found_marker_index][3] )
{
cursor.row++;
col_offset = 0;
}
}
else
{
if ( 'undefined' == typeof syntax_map[cursor.row+num_block_rows] )
{
syntax_map[cursor.row+num_block_rows-1] = [];
}
syntax_map[cursor.row+num_block_rows-1].push([token_type, -1, cursor_col_end + end_marker_len, '']);
// var a = block_source.split('\n');
col_offset = cursor_col_end + end_marker_len;
cursor.row += num_block_rows -1;
}
// console.log(num_block_rows);
source = source.substr(end_index+end_marker_len);
}
}
delete ixs;
delete source;
var n = Math.max(syntax_map.length, this.syntax_map.length);
for ( i=0; i'.embed(inner_node.style.color, inner_node.style.background, inner_node.style.fontStyle, inner_node.style.fontWeight, inner_node.style.textDecoration) + get_inner(inner_node) + '';
}
}
return ht;
}
var nodes = this.nodeEditArea.childNodes;
var ht = '';
for (var i=0; i?'.embed(pre.style.minHeight, get_inner(pre));
}
return ht;
}
function ch_encode_markup(str)
{
if ( -1 != str.indexOf('&') )
{
str = str.replace(/&/g, '&');
}
if ( -1 != str.indexOf('>') )
{
str = str.replace(/>/g, '>');
}
if ( -1 != str.indexOf('<') )
{
str = str.replace( / 1 2 3 = 1 2 3
function ch_encode_markup_spaces(str)
{
var n = str.length - str.replace(/ /g, '').length;
for ( var i=0; i/g, '').length);
return arguments[1]+(is_inside?'~`~`~`~`':' ');
});
}
return str.replace(/~`~`~`~`/g, ' ');
}
ac.chap.View.prototype.getRenderedCharDimension = function(rowIndex, colIndex)
{
return [this.options.colWidth, this.options.rowHeight];
}
ac.chap.View.prototype.getRenderedStringDimension = function(rowIndex, colIndex, width)
{
if ( 'undefined' != typeof this.window.char_map[rowIndex] )
{
if ( colIndex < this.window.char_map[rowIndex].length )
{
var str = this.window.char_map[rowIndex].substr(colIndex, width);
var ix = 0;
var tab = this.options.tabelator;
while ( -1 != ix )
{
ix = str.indexOf('\t');
if ( -1 != ix )
{
str = str.substr(0,ix)+tab.substr(0, tab.length-(ix % tab.length))+str.substr(ix+1);
}
}
// console.log('(getrenderedstringdimension) = [%s], ix:%s w:%s %s', this.options.colWidth*str.length, colIndex, width, str);
return [this.options.colWidth*str.length, this.options.rowHeight];
}
}
return [0,0];
}
ac.chap.View.prototype.getVirtualStringDimension = function(row, colIndex, width)
{
if ( colIndex < row.length )
{
var str = row.substr(colIndex, width);
var ix = 0;
var tab = this.options.tabelator;
while ( -1 != ix )
{
ix = str.indexOf('\t');
if ( -1 != ix )
{
str = str.substr(0,ix)+tab.substr(0, tab.length-(ix % tab.length))+str.substr(ix+1);
}
}
// console.log('(getrenderedstringdimension) = [%s], ix:%s w:%s %s', this.options.colWidth*str.length, colIndex, width, str);
return [this.options.colWidth*str.length, this.options.rowHeight];
}
return [0,0];
}
ac.chap.View.prototype.getRenderedCharPosition = function(rowIndex, colIndex)
{
var node_row = this.getRowNode(rowIndex);
if ( null != node_row && null != node_row.parentNode )
{
var offset_x = this.getRenderedStringDimension(rowIndex, 0, colIndex)[0];
var offset_y = 0;
var dim = this.getRenderedCharDimension(rowIndex, colIndex);
offset_x -= dim[0];
if ( this.options.wordWrap )
{
if ( 0 < colIndex )
{
var w = this.options.colWidth * (this.numCols);
offset_y = this.options.rowHeight * (Math.floor(offset_x/w));
offset_x = (offset_x) % w;
}
}
return [offset_x, node_row.offsetTop+offset_y, node_row];
}
return null;
}
ac.chap.View.prototype.getRowNode = function(rowIndex)
{
return document.getElementById('row-'+this.window.instanceId+'-'+this.index+'-'+rowIndex);
}
ac.chap.View.prototype.getVirtualCharPosition = function(nodeRow, row, colIndex)
{
var offset_x = this.getVirtualStringDimension(row, 0, colIndex)[0];
var offset_y = 0;
var dim = this.getRenderedCharDimension(0, colIndex);
offset_x -= dim[0];
if ( this.options.wordWrap )
{
if ( 0 < colIndex )
{
var w = this.options.colWidth * (this.numCols);
offset_y = this.options.rowHeight * (Math.floor(offset_x/w));
offset_x = (offset_x) % w;
}
}
return [offset_x, nodeRow.offsetTop+offset_y];
}
ac.chap.View.prototype.showCaret = function(skipScroll)
{
var caret_row = this.window.caret.position[0];
var caret_col = this.window.caret.position[1];
pos = this.getRenderedCharPosition(caret_row, caret_col);
if ( null != pos )
{
// caret is visible
var node_row = pos[2];
var node = document.getElementById('ac-chap-caret-'+this.window.instanceId);
if ( null != node )
{
node.parentNode.removeChild(node);
}
if ( 1 == this.window.state.caretPhase )
{
// displaying caret
node = document.createElement('div');
node.id = 'ac-chap-caret-'+this.window.instanceId;
node.style.position = 'absolute';
node.style.font = '1px arial'; // IE
node.style.width = this.options.colWidth + 'px';
node.style.height = this.options.rowHeight + 'px';
pos[2] = this.options.colWidth;
pos[3] = this.options.rowHeight;
pos = this.theme.adjustCaretPosition(this.window.caret.mode, pos);
node.style.left = pos[0]+'px';
node.style.top = pos[1]+'px';
this.theme.renderCaret(this.window.caret.mode, node);
this.nodeCaret = node_row.appendChild(node);
node_row.style.background = this.theme.caretRowStyleActive;
if ( !skipScroll )
{
// might be out of borders, at least partially
if ( 0 > node_row.offsetTop - (this.nodeScrollArea.$.scrollTop % this.options.rowHeight) )
{
// top margin overlay, first rendered row is partially hidden
this.scrollToRow(caret_row);
}
else if ( node_row.offsetTop > this.options.rowHeight*(this.numRows-1)-$__tune.ui.scrollbarWidth )
{
// bottom margin overlay
this.scrollToRow(caret_row-Math.floor(this.numRows/2));
}
}
this.nodeCaretRow = node_row;
}
if ('undefined' != typeof this.state.lastCaretRowIndex && this.state.lastCaretRowIndex != caret_row)
{
var last_node_row = this.getRowNode(this.state.lastCaretRowIndex);
if (last_node_row)
{
last_node_row.style.background = 'transparent';
}
}
this.state.lastCaretRowIndex = caret_row;
}
else
{
if ( !skipScroll )
{
// scrolling into view
this.scrollToRow(caret_row - Math.floor(this.numRows/2));
}
}
}
ac.chap.View.prototype.hideCaret = function(skipCaretRow)
{
if ( null != this.nodeCaret && null != this.nodeCaret.parentNode )
{
this.nodeCaret.parentNode.removeChild(this.nodeCaret);
this.nodeCaret = null;
}
if ( !skipCaretRow && null != this.nodeCaretRow )
{
// console.log('off(hide) caret line background for %s', this.nodeCaretRow.id);
this.nodeCaretRow.style.background = 'transparent';
}
// console.log('hide caret');
}
ac.chap.View.prototype.scrollToRow = function(rowIndex, setCaretToo, dontRefreshCaret)
{
this.nodeScrollArea.$.scrollTop = this.options.rowHeight * rowIndex - Math.floor(this.nodeRoot.$.offsetHeight/3);
if (setCaretToo)
{
this.window.runAction(ac.chap.ACTION_CARET, {moveTo:[rowIndex, 0]});
this.window.runAction(ac.chap.ACTION_CARET, {move:'row_end'});
}
if (!dontRefreshCaret)
{
this.window.state.caretPhase = 1;
this.showCaret(true);
}
}
ac.chap.View.prototype.expandFolding = function(rowIndex)
{
if ( 'undefined' == typeof this.window.row_id_map[this.index][rowIndex] )
{
return;
}
var row_state = this.window.row_id_map[this.index][rowIndex][2];
if (0 == (ac.chap.ROWSTATE_FOLD_EXPAND & row_state))
{
return;
}
var end_row_index = this.window.row_id_map[this.index][rowIndex][3][1];
this.window.row_id_map[this.index][rowIndex][2] &= (65535 - ac.chap.ROWSTATE_FOLD_EXPAND);
this.window.row_id_map[this.index][rowIndex][1] = false;
for ( var i=rowIndex+1; i<=end_row_index; i++ )
{
this.window.row_id_map[this.index][i][1] = false;
this.window.row_id_map[this.index][i][2] &= (65535 - ac.chap.ROWSTATE_FOLD_COLLAPSED);
}
this.recalculateVisibleRows();
var me = this;
// console.log('expanding: %i, start: %i', rowIndex, end_row_index);
$runafter(40, function(){me.renderText(true)});
}
ac.chap.View.prototype.resize = function()
{
var h = this.nodeRoot.p().h();
this.nodeRoot.h(h);
$(this.nodeSidebar).h(h);
this.nodeScrollArea.h(h);
this.nodeFillArea.h(h-$__tune.ui.scrollbarWidth);
$(this.nodeSelectionArea).h(h-$__tune.ui.scrollbarWidth+this.options.rowHeight);
this.recalculateNumRows();
this.recalculateVisibleRows();
this.renderText(true);
}
ac.chap.View.prototype.reloadOptions = function()
{
this.calculateColRowDim();
this.recalculateNumCols(false, true);
this.recalculateNumRows();
this.recalculateVisibleRows();
this.renderSidebarStub();
this.renderText(true);
}
ac.chap.View.prototype.recalculateNumCols = function(node, withoutScrollbar)
{
node = node || this.nodeRoot;
var w = node.$.offsetWidth;
if (withoutScrollbar)
{
w -= $__tune.ui.scrollbarWidth+61;
}
this.numCols = Math.floor(w/this.options.colWidth);
}
ac.chap.View.prototype.recalculateNumRows = function(node)
{
node = node || this.nodeRoot;
this.numRows = Math.floor(node.$.offsetHeight/this.options.rowHeight);
}
ac.chap.View.prototype.showInteractiveSearch = function()
{
this.hideInteractiveSearch();
var pos = this.nodeRoot.abspos();
var node = $().a($$()).pos(true).x(pos.x+58).y(pos.y).z(2000).w(this.nodeRoot.w()-$__tune.ui.scrollbarWidth-61).h(24).o(0.8);
node.s('background:#000;border:1px solid #777;border-top:0;');
var search_key_id = 'is_key_?'.embed(this.window.ident);
var ht = '';
node.t(ht);
var me = this;
var status_node = node.g('td:0');
var search_key_node = node.g('input:0');
var original_caret_pos = [me.window.caret.position[0], me.window.caret.position[1]];
var last_keyword = '';
var selection = me.window.getSelection();
search_key_node.e('keydown', function(evt)
{
evt.stopPropagation();
if (40 == evt.keyCode)
{
me.window.runAction(ac.chap.ACTION_CUSTOM, {action:'SearchKeyword', direction:'down'});
me.scrollToRow(me.window.caret.position[0], false, true);
me.window.processActionResult(true, true);
evt.preventDefault();
return true;
}
else if (38 == evt.keyCode)
{
me.window.runAction(ac.chap.ACTION_CUSTOM, {action:'SearchKeyword', direction:'up'});
me.scrollToRow(me.window.caret.position[0], false, true);
me.window.processActionResult(true, true);
evt.preventDefault();
return true;
}
else if (27 == evt.keyCode)
{
finish(true);
evt.preventDefault();
return true;
}
else if (13 == evt.keyCode)
{
finish();
evt.preventDefault();
return true;
}
}).e('keyup', function(evt)
{
evt.stopPropagation();
search();
}).$.focus();
node.g('img:0').e('click', function(evt)
{
evt.stopPropagation();
finish(true);
});
function finish(canceled)
{
if (canceled)
{
me.window.removeSelection();
me.window.runAction(ac.chap.ACTION_CARET, {moveTo:[original_caret_pos[0], original_caret_pos[1]]});
me.scrollToRow(me.window.caret.position[0], false, true);
me.window.processActionResult(true, true);
}
ac.chap.setActiveComponent(me.window);
me.hideInteractiveSearch();
}
function update_status(numFound)
{
status_node.t('Found ? results.'.embed(numFound));
}
function search()
{
var keyword = search_key_node.$.value.trim();
if ('' == keyword || last_keyword == keyword)
{
if ('' == keyword)
{
update_status(0);
}
return;
}
update_status(me.window.getText().split(keyword).length - 1);
last_keyword = keyword;
me.window.removeSelection();
me.window.runAction(ac.chap.ACTION_CARET, {moveTo:[original_caret_pos[0], original_caret_pos[1]]});
me.window.runAction(ac.chap.ACTION_CUSTOM, {action:'SetSearchKeyword', keyword:keyword});
me.window.runAction(ac.chap.ACTION_CUSTOM, {action:'SearchKeyword', direction:'down'});
me.scrollToRow(me.window.caret.position[0], false, true);
me.window.processActionResult(true, true);
}
if (null != selection)
{
search_key_node.$.value = selection;
search_key_node.$.select();
search_key_node.$.focus();
search();
}
this.interactiveSearchNode = node;
}
ac.chap.View.prototype.hideInteractiveSearch = function()
{
if (this.interactiveSearchNode && this.interactiveSearchNode.is())
{
this.interactiveSearchNode.rs();
}
}
ac.chap.View.prototype.render = function(node)
{
var w = node.$.offsetWidth;
var h = node.$.offsetHeight;
this.recalculateNumRows(node);
this.recalculateNumCols(node);
node.sa('chap-view', 'true');
var me = this;
this.nodeRoot = node.a($$()).pos(true).w(w).h(h).n('acw-chap').s('background:?'.embed(this.theme.background));
this.interactiveSearchNode = null;
var w_rows = 58;
w -= w_rows;
this.nodeSidebar = this.nodeRoot.a($$()).pos(true).x(0).y(0).w(w_rows).h(h).s('overflow:hidden').n('sidebar');
// rendering sidebar stub
this.renderSidebarStub();
this.nodeScrollArea = this.nodeRoot.a($$()).pos(true).x(w_rows).y(0).w(w).h(h).n('scroll-area').s('overflow:auto');
this.nodeScrollArea.e('scroll', function(evt)
{
var offset = Math.floor(me.nodeScrollArea.$.scrollTop/me.options.rowHeight);
var map = me.window.row_id_map[me.index];
var row_index = 0;
for ( var i=0; i' + ch_encode_markup(token[1]) + '';
}
else
{
rend_chunk += ch_encode_markup(token[1]);
}
i += token[1].length - 1;
// offset = i + token[1].length;
offset = i + 1;
// console.log(token, offset, rend_chunk);
}
rend_chunk += ch_encode_markup(chunk.substr(offset));
chunk = rend_chunk;
}
else
{
chunk = ch_encode_markup(chunk);
}
return chunk;
}
ac.chap.View.prototype.renderTextRow = function(node, rowIndex, renderedPreviously)
{
var row = this.window.char_map[rowIndex];
var rendered_row = '';
var offset = 0;
var font_style = ';font:' + this.window.options.font.size + 'px ' + this.window.options.font.family;
var interpolation = this.window.language.stringInterpolation;
var row_state = this.window.row_id_map[this.index][rowIndex][2];
if ( 'undefined' != typeof this.window.syntax_map[rowIndex] && 0 < this.window.syntax_map[rowIndex].length )
{
// console.log(this.window.syntax_map[rowIndex]);
var n = this.window.syntax_map[rowIndex].length;
for ( var i=0; i' + ch_encode_markup(chunk.substring(0, m.index)) + '';
new_chunk += this.renderChunk(chunk.substr(m.index, m[interpolation[1]].length));
chunk = chunk.substr(m.index + m[interpolation[1]].length);
// console.warn(chunk);
}
new_chunk += '' + ch_encode_markup(chunk) + '';
// console.info(new_chunk);
rendered_row += new_chunk;
}
else
{
rendered_row += ''+ch_encode_markup(chunk)+'';
// console.log(rendered_row);
}
}
else
{
rendered_row += ch_encode_markup(chunk);
}
offset = -1 == end_offset ? row.length : end_offset;
}
}
rendered_row += this.renderChunk(row.substr(offset));
// console.log(rendered_row);
// rendering custom selection (search results, errors and such)
// !!!!!!!!!!
// NOT USED NOW !!!!!
// !!!!!!!!!!
// !!!!!!!!!!
// !!!!!!!!!!
// !!!!!!!!!!
if ( false && ac.chap.ROWSTATE_SELECTION == (row_state & ac.chap.ROWSTATE_SELECTION) )
{
var range = this.window.row_id_map[this.index][rowIndex][5];
if ( 0 == range[0] && this.window.char_map[rowIndex].length == range[1] )
{
rendered_row = ''+rendered_row+'';
}
else
{
// console.log(range);
var raw = rendered_row;
var n = raw.length;
var col_index = 0;
var selection_started = false;
var offset = 0;
// console.log('before: %s', raw);
for ( var i=0; i');
i += ix;
// console.log('ix: %s', ix);
if ( selection_started )
{
var c = '';
rendered_row = rendered_row.substr(0, i+offset+1)+c+rendered_row.substr(i+offset+1);
offset += c.length;
}
continue;
}
if ( range[0] == col_index )
{
selection_started = true;
var c = '';
rendered_row = rendered_row.substr(0, i+offset)+c+rendered_row.substr(i+offset);
offset += c.length;
}
if ( selection_started && range[1]-1 < col_index )
{
selection_started = false;
var c = '';
rendered_row = rendered_row.substr(0, i+offset)+c+rendered_row.substr(i+offset);
break;
}
if ( '&' == ch )
{
if ( '<' == raw.substr(i, 4) || '>' == raw.substr(i, 4) )
{
i += 3;
}
else if ( '&' == raw.substr(i, 5) )
{
i += 4;
}
}
col_index++;
}
if ( selection_started )
{
rendered_row += '';
}
}
}
// console.log(rendered_row);
// making intelligent tabelators - note, using simple replace of \t doesn't work
var ix = 0;
var tab = this.options.tabelator;
var raw = this.window.char_map[rowIndex];
var tab_stack = [];
while ( -1 != ix )
{
ix = raw.indexOf('\t');
if ( -1 != ix )
{
var tab_length = tab.length - (ix % tab.length);
raw = raw.substr(0,ix)+tab.substr(0, tab_length)+raw.substr(ix+1);
tab_stack.push(tab_length);
}
}
for ( var i=0; i');
if ( -1 == ix )
{
break;
}
i += ix;
continue;
}
var n_ch = 0;
if ( '&' == ch )
{
if ( '<' == rendered_row.substr(i,4) || '>' == rendered_row.substr(i,4) )
{
n_ch = 3;
}
else if ( '&' == rendered_row.substr(i,5) )
{
n_ch = 4;
}
}
printable += ch.charAt(0);
if ( this.numCols == printable.length )
{
raw = raw.substr(0, i+offset+n_ch)+'
'+raw.substr(i+offset+n_ch);
num_subrows++;
offset += 4;
printable = '';
}
i += n_ch;
}
rendered_row = raw;
}
if ( ac.chap.ROWSTATE_FOLD_EXPAND == (row_state & ac.chap.ROWSTATE_FOLD_EXPAND) )
{
var end_index = this.window.row_id_map[this.index][rowIndex][3][1];
var content = ch_encode_markup(this.window.char_map.slice(rowIndex, end_index+1).join('\n').replace(/"/ig, "''"));
rendered_row += ''.embed(content);
}
node.setAttribute('num-subrows', num_subrows);
if ( $__tune.isIE )
{
// IE trims input source in innerHTML
rendered_row = ch_encode_markup_spaces(rendered_row);
}
node.innerHTML = rendered_row;
}
ac.chap.View.prototype.recalculateVisibleRows = function()
{
var map = this.window.row_id_map[this.index];
var n = map.length;
var i = 0;
var num_visibles = 0;
while ( i < n )
{
var state = map[i][2];
if ( 0 == (ac.chap.ROWSTATE_FOLD_COLLAPSED & state) )
{
num_visibles++;
}
i++;
}
this.numVisibleRows = num_visibles;
}
ac.chap.View.prototype.getVisibleRowIndices = function()
{
var map = this.window.row_id_map[this.index];
var i = 0;
var index = this.startRow;
var indices = [];
while ( i++ <= this.numRows )
{
if ( 'undefined' == typeof this.window.row_id_map[this.index][index] )
{
break;
}
var state = this.window.row_id_map[this.index][index][2];
if ( ac.chap.ROWSTATE_FOLD_COLLAPSED == (ac.chap.ROWSTATE_FOLD_COLLAPSED & state) )
{
// collapsed
i--;
index++;
continue;
}
indices.push(index);
if ( ac.chap.ROWSTATE_FOLD_EXPAND == (state & ac.chap.ROWSTATE_FOLD_EXPAND) )
{
// collapsed folding
var refered_row_index = this.window.row_id_map[this.index][index][3][1];
index = refered_row_index + 1;
}
else
{
index++;
}
}
return indices;
}
ac.chap.View.prototype.renderRowSidebar = function(position, rowIndex, rowNode, forceCompleteRedraw)
{
if (!this.nodeSidebar.firstChild.childNodes.item(position))
{
return;
}
var bar_node = this.nodeSidebar.firstChild.childNodes.item(position).firstChild;
if ( 0 == rowNode.offsetHeight )
{
rowNode.style.height = this.options.rowHeight;
}
var num_subrows = parseInt(rowNode.getAttribute('num-subrows'));
var cache_id = forceCompleteRedraw ? 'none' : (num_subrows+':'+this.window.row_id_map[this.index][rowIndex].join('-'));
if (bar_node.getAttribute('sidebar-cache-id') == cache_id && 'none' != cache_id)
{
return;
}
if ('none' != cache_id)
{
bar_node.setAttribute('sidebar-cache-id', cache_id);
bar_node.firstChild.style.fontSize = (this.window.options.font.size-2) + 'px';
}
// console.log(cache_id);
var row_height = num_subrows * this.options.rowHeight;
bar_node.parentNode.style.height = row_height + 'px';
if (forceCompleteRedraw)
{
bar_node.firstChild.style.fontSize = (this.window.options.font.size-2) + 'px';
}
var ht = rowIndex+1;
if ( this.options.wordWrap )
{
var htt = '';
for ( var i=1; i this.numCols )
{
ix_r++;
ix_c -= this.numCols;
}
if ( ii == range[1] )
{
offset[2] = ix_r;
offset[3] = ix_c;
break;
}
}
if ( -1 == offset[3] )
{
offset[2] = ix_r+1;//offset[0]+1;
}
node_row_selection.style.top = (node_row.offsetTop + this.options.rowHeight*offset[0]) + 'px';
// console.log('%o', offset);
if ( offset[0] == offset[2] )
{
// selection stays non-wrapped
node_row_selection.style.left = offset[1]*this.options.colWidth + 'px';
node_row_selection.style.width = ((offset[3]-offset[1])*this.options.colWidth) + 'px';
// console.log(node_row_selection.style.width);
}
else
{
// finishing current node
if ( -1 == offset[1] )
{
// caret stays on the end of the row
node_row_selection.style.left = (ix_c*this.options.colWidth) + 'px';
node_row_selection.style.width = (node_row.offsetWidth - (ix_c*this.options.colWidth)) + 'px';
}
else
{
node_row_selection.style.left = (offset[1]*this.options.colWidth) + 'px';
node_row_selection.style.width = (node_row.offsetWidth - (offset[1]*this.options.colWidth)) + 'px';
}
// marking as non-cacheable
node_row_selection.removeAttribute('cachid');
// creating additional ones
for ( ii=offset[0]+1; ii<=offset[2]; ii++ )
{
node_row_selection = node_cache.appendChild(document.createElement('div'));
node_row_selection.style.background = this.theme.selectionStyle;
node_row_selection.style.position = 'absolute';
node_row_selection.style.left = '0px';
node_row_selection.style.top = (node_row.offsetTop+ii*this.options.rowHeight) + 'px';
node_row_selection.style.height = this.options.rowHeight + 'px';
if ( ii != offset[2] )
{
node_row_selection.style.width = node_row.offsetWidth + 'px';
}
else
{
node_row_selection.style.width = ((offset[3])*this.options.colWidth) + 'px';
}
}
}
}
else
{
var offset_x1 = this.getRenderedStringDimension(row_index, 0, range[0])[0];
var offset_x2 = this.getRenderedStringDimension(row_index, 0, range[1]+1)[0];
node_row_selection.style.left = offset_x1 + 'px';
node_row_selection.style.width = (offset_x2 - offset_x1) + 'px';
}
}
}
// console.log('selection after range: %o', this.window.row_id_map[this.index][row_index][3]);
}
}
// console.log('%o', this.window.row_id_map[this.index][0]);
var ht = node_cache.innerHTML;
this.nodeSelectionArea.innerHTML = ht;
}
ac.chap.View.prototype.renderText = function(forceCompleteRedraw)
{
var row_indices = this.getVisibleRowIndices();
var num_rows = row_indices.length;
// console.log('view: %s - row indices: %o', this.index, row_indices);
// console.log('view: %s - num rows x cols [%s x %s]', this.index, this.numRows, this.numCols);
// checking to see if only one row changed - the most usual case
var changed_row_index = -1;
var changed_row_position = -1;
for ( var i=0; i fill_area_h )
{
fill_area_h = this.nodeRoot.h()-$__tune.ui.scrollbarWidth;
}
this.nodeFillArea.h(fill_area_h);
}
else
{
this.nodeEditAreaCache.innerHTML = '';
}
if ( parseInt(this.nodeSidebar.firstChild.style.top) != top_offset )
{
this.nodeSidebar.firstChild.style.top = (top_offset)+'px';
this.nodeSidebar.firstChild.style.height = (this.nodeSidebar.offsetHeight - $__tune.ui.scrollbarWidth - top_offset)+'px';
}
this.renderSelection();
}
/*
* ac.Chap - Text Editing Component widget - Settings file
*/
if ( 'undefined' == typeof ac )
{
var ac = {chap:{}};
}
$class('ac.chap.KeyMap',
{
construct:function()
{
this.definition = {};
this.isMac = true;
this.wordCompleteCache = null;
this.snippetCompleteCache = null;
this.searchKeyword = '';
this.initDefinition();
}
});
ac.chap.KeyMap.prototype.initDefinition = function()
{
}
ac.chap.KeyMap.prototype.importCommands = function(commands)
{
var n = commands.length;
for ( var i=0; i looking_for_len && words_prev[i+1].substr(0, looking_for_len) == looking_for )
{
if ( -1 == found_words_index.indexOf(' '+words_prev[i+1]) )
{
found_words.push(words_prev[i+1]);
found_words_index += ' '+words_prev[i+1];
}
}
if ( words_next[i] && words_next[i].length > looking_for_len && words_next[i].substr(0, looking_for_len) == looking_for )
{
if ( -1 == found_words_index.indexOf(' '+words_next[i]) )
{
found_words.push(words_next[i]);
found_words_index += ' '+words_next[i];
}
}
}
if ( 1 < found_words.length )
{
// console.log('results found: %o', found_words);
wcc.results = found_words;
wcc.index = 0;
proceed_complete = true;
}
}
else
{
proceed_complete = true;
}
var num_results = wcc.results.length;
if ( proceed_complete && 0 < num_results )
{
var index = wcc.index;
index += params.direction ? 1 : -1;
if ( num_results <= index )
{
index = 0;
}
else if ( 0 > index )
{
index = num_results-1;
}
// console.log('n:%s i:%s', num_results, index);
// let's not add the following operation to the transaction/undo log
component.stopTransactionLog();
component.runAction(ac.chap.ACTION_CARET, {move:'prev_word'});
component.runAction(ac.chap.ACTION_SELECTION, {add:true});
component.runAction(ac.chap.ACTION_DELETE, {character:false});
component.runAction(ac.chap.ACTION_INSERT, {string:wcc.results[index]});
component.startTransactionLog();
wcc.index = index;
wcc.position = [component.caret.position[0], component.caret.position[1]];
}
else
{
wcc.results = [];
}
this.wordCompleteCache = wcc;
return ac.chap.ACTION_RES_REDRAWCARET | ac.chap.ACTION_RES_REDRAWTEXT;
}
ac.chap.KeyMap.prototype.getAffectedRows = function(component, caretRow)
{
var from_row = caretRow;
var to_row = caretRow;
if (null != component.selection)
{
var start_pos = component.selection.startPosition[0];
var end_pos = component.selection.endPosition[0];
if (-1 == component.selection.endPosition[1])
{
end_pos--;
}
from_row = Math.min(start_pos, end_pos);
to_row = Math.max(start_pos, end_pos);
}
return [from_row, to_row];
}
ac.chap.KeyMap.prototype.action_Indent = function(keyCode, controlKeysMask, caretRow, caretCol, component, params)
{
var affected_rows = this.getAffectedRows(component, caretRow);
var tab = component.getTabelator();
for (var i=affected_rows[0]; i<=affected_rows[1]; i++)
{
if ('right' == params.direction)
{
component.insertIntoCharacterMap(tab, i, 0);
}
else
{
var row = component.char_map[i];
var index = 0;
while (('\t' == row.charAt(index) || ' ' == row.charAt(index)) && (row.length > index) && (tab.length > index)) index++;
if (0 < index)
{
component.removeFromCharacterMap(i, 0, i, index);
}
}
}
return ac.chap.ACTION_RES_REDRAWCARET | ac.chap.ACTION_RES_REDRAWTEXT | ac.chap.ACTION_RES_SELECTIONCHANGED;
}
ac.chap.KeyMap.prototype.action_Comment = function(keyCode, controlKeysMask, caretRow, caretCol, component, params)
{
if (!component.language)
{
return 0;
}
var markers = component.language.singleRowCommentStartMarkers;
if (0 == markers.length)
{
return 0;
}
var marker = markers[0];
var tab = component.getTabelator();
var affected_rows = this.getAffectedRows(component, caretRow);
var tab = component.getTabelator();
var prepend_text = marker + ' ';
for (var i=affected_rows[0]; i<=affected_rows[1]; i++)
{
var row = component.char_map[i];
var index = row.indexOf(marker);
if (-1 != index && 0 == row.substring(0, index).replace(tab, '').replace(' ', ''))
{
// was commented
component.removeFromCharacterMap(i, 0, i, index+marker.length);
}
else
{
// will be commented
component.insertIntoCharacterMap(marker, i, 0);
}
}
return ac.chap.ACTION_RES_REDRAWCARET | ac.chap.ACTION_RES_REDRAWTEXT | ac.chap.ACTION_RES_SELECTIONCHANGED;
}
ac.chap.KeyMap.prototype.action_RuntimeOption = function(keyCode, controlKeysMask, caretRow, caretCol, component, params)
{
component.setRuntimeOption(params['key'], params['value']);
return ac.chap.ACTION_RES_REDRAWCARET | ac.chap.ACTION_RES_REDRAWTEXT | ac.chap.ACTION_RES_SELECTIONCHANGED;
}
ac.chap.KeyMap.prototype.action_SearchInteractive = function(keyCode, controlKeysMask, caretRow, caretCol, component, params)
{
component.showInteractiveSearch();
return ac.chap.ACTION_RES_REDRAWCARET | ac.chap.ACTION_RES_SELECTIONCHANGED;
}
ac.chap.KeyMap.prototype.action_SetSearchKeyword = function(keyCode, controlKeysMask, caretRow, caretCol, component, params)
{
if (params['keyword'])
{
this.searchKeyword = params['keyword'];
return 0;
}
if (component.selection && component.selection.startPosition[0] == component.selection.endPosition[0])
{
this.searchKeyword = component.getSelection();
return ac.chap.ACTION_RES_SELECTIONCHANGED;
}
return 0;
}
ac.chap.KeyMap.prototype.action_SearchKeyword = function(keyCode, controlKeysMask, caretRow, caretCol, component, params)
{
if ('' == this.searchKeyword)
{
return 0;
}
row_index = caretRow;
var index = 0;
var search_down = 'down' == params['direction'];
do
{
var row = component.char_map[row_index];
var offset = 0;
console.log(ac.chap.activeComponent.activeView);
if (row_index == caretRow)
{
if (search_down)
{
// if (row.substring(caretCol, this.searchKeyword.length) == this.searchKeyword)
// {
// // offset = this.searchKeyword.length;
// }
row = row.substr(caretCol)
offset += caretCol;
}
else
{
if (row.substring(caretCol-this.searchKeyword.length, caretCol))
{
offset = this.searchKeyword.length;
}
row = row.substring(0, caretCol - offset);
offset = 0;
}
}
index = search_down ? row.indexOf(this.searchKeyword) : row.lastIndexOf(this.searchKeyword);
if (-1 != index)
{
index += offset;
component.runAction(ac.chap.ACTION_SELECTION, {remove:true});
component.runAction(ac.chap.ACTION_CARET, {moveTo:[row_index, index]});
component.runAction(ac.chap.ACTION_CARET, {store:true});
component.runAction(ac.chap.ACTION_CARET, {moveTo:[row_index, index+this.searchKeyword.length]});
component.runAction(ac.chap.ACTION_SELECTION, {add:true});
return ac.chap.ACTION_RES_REDRAWCARET | ac.chap.ACTION_RES_SELECTIONCHANGED | ac.chap.ACTION_RES_SCROLLTOCARET;
}
row_index += search_down ? 1 : -1;
if (search_down && row_index == component.char_map.length)
{
row_index = 0;
}
else if (!search_down && -1 == row_index)
{
row_index = component.char_map.length-1;
}
}
while (caretRow != row_index);
return ac.chap.ACTION_RES_REDRAWCARET | ac.chap.ACTION_RES_SELECTIONCHANGED;
}
ac.chap.KeyMap.prototype.action_SmartIndent = function(keyCode, controlKeysMask, caretRow, caretCol, component, params)
{
// console.log(params);
var line = component.getLineAt(caretRow);
var m = params['indent_tab_when_ends'] ? line.match(/^([ \t]*)(.*)$/) : line.match(/^([ \t]*)([^ \t]*)/);
// console.log(m);
var prepend_text = m[1];
if (params['indent_tab_when_ends'] || params['indent_tab_when_starts'])
{
m[2] = m[2].trim();
var indent_when_values = params['indent_tab_when_ends'] ? params['indent_tab_when_ends'].split(' ') : params['indent_tab_when_starts'].split(' ');
for (var i=0; i#');
code = code.substr(start_ix+4, m[3].length)+'##'+code.substr(start_ix+m[0].length-m[1].length);
any_change = true;
}
else
{
break;
}
}
code_chunks.push(code);
code = code_chunks.join('');
}
re = /##/;
while ( true )
{
m = re.exec(code)
if ( null == m )
{
break;
}
tabstops[m[1]][1] = tabstops[m[1]][1].replace(/##/g, '');
tabstops[m[1]][2] = m.index;
tabstops[m[1]][3] = tabstops[m[1]][1].length;
code = code.substr(0, m.index)+code.substr(m.index+m[0].length).replace('##', '');
}
// [getting mirrors]
re = /\{\$\{(\d)\:([^\}]*)\}\}/;
while ( true )
{
m = re.exec(code)
if ( null == m )
{
break;
}
code = code.substr(0, m.index)+m[2]+code.substr(m.index+m[0].length);
var ix_end = code.indexOf('{$'+m[1]+'}');
if ( -1 == ix_end )
{
console.error('Invalid snippet definition. Mirror `?` does not have `{$?}` mirrored location specified.'.embed(m[1], m[1]));
break;
}
tabstops[m[1]] = ['mi', m[2], m.index, m[2].length, ix_end];
if ( m.index > ix_end )
{
console.error('Unsupported feature. Mirror `?` should have mirrored location positioned AFTER itself.'.embed(m[1]));
}
code = code.substr(0, ix_end)+code.substr(ix_end+4);
}
// [getting tabstops]
re = /(^|[^\\])\$(\d)/;
while (true)
{
m = re.exec(code);
if ( null == m )
{
break;
}
tab_id = m[2];
if ( tabstops[tab_id] )
{
console.error('Invalid snippet definition. Tabstop `?` already defined as placeholder at position `?`. Snippet source: `?`.'.embed(tab_id, m.index, code));
break;
}
var start_ix = m.index+m[1].length;
tabstops[tab_id] = ['ts', '', start_ix, 0];
code = code.substr(0, start_ix)+code.substr(start_ix+2);
var offset = m[1].length + 2;
for ( var tab_id in tabstops )
{
// console.log('adjusting: %s, %s < %s', tab_id, start_ix, tabstops[tab_id][2]);
if ( 'mi' == tabstops[tab_id][0] )
{
if ( start_ix < tabstops[tab_id][2] )
{
tabstops[tab_id][2] -= offset;
}
if ( start_ix < tabstops[tab_id][4] )
{
tabstops[tab_id][4] -= offset;
}
}
else if ( 'ph' == tabstops[tab_id][0] && start_ix < tabstops[tab_id][2] )
{
tabstops[tab_id][2] -= offset;
}
}
}
// $0 not defined, will be at the end of the snippet by default
if ( !tabstops[0] )
{
tabstops[0] = ['ts', '', code.length, 0];
}
// [postprocessing - unescape]
code = code.replace(/\0/g, '$');
for ( var tab_id in tabstops )
{
var placeholder = tabstops[tab_id];
// console.log('#%s : %o', tab_id, placeholder);
}
var scc =
{
firstInitialized:true,
insertCaretPosition:[caretRow, caretCol],
tabstops: tabstops,
callbackIndex: -1,
activeTabStopIndex:tabstops[1] ? 1 : 0,
activeTabStopRange:[],
activeTabStopContent:'',
activeTabStopNested:[],
wasSelection:wasSelection,
tabActivation:tabActivation
}
if ( !scc.wasSelection )
{
component.runAction(ac.chap.ACTION_CARET, {move:'prev_word'});
component.runAction(ac.chap.ACTION_SELECTION, {add:true});
component.runAction(ac.chap.ACTION_DELETE, {character:true});
}
var tabstop = tabstops[scc.activeTabStopIndex];
component.runAction(ac.chap.ACTION_INSERT, {string:code.substr(0, tabstop[2])});
component.runAction(ac.chap.ACTION_INSERT, {string:code.substr(tabstop[2]), skipCaretChange:true});
// selecting default value
var selection_changed = false;
if ( '' != tabstop[1] )
{
component.runAction(ac.chap.ACTION_CARET, {store:true});
component.runAction(ac.chap.ACTION_CARET, {moveBy:'column', value:tabstop[1].length});
component.runAction(ac.chap.ACTION_SELECTION, {add:true});
selection_changed = true;
}
if ( 0 != scc.activeTabStopIndex )
{
// starting action listener
this.snippetCompleteCache = scc;
this.snippetCompleteCache.callbackIndex = component.addActionListener(ac.chap.ACTION_LISTENER_BOTH, this, this.snippetCompleteActionListener);
}
}
return ac.chap.ACTION_RES_REDRAWCARET | ac.chap.ACTION_RES_REDRAWTEXT | (selection_changed ? ac.chap.ACTION_RES_SELECTIONCHANGED : 0);
// return ac.chap.ACTION_RES_REDRAWCARET | ac.chap.ACTION_RES_REDRAWTEXT;
}
ac.chap.KeyMap.prototype.snippetCompleteActionListener = function(component, action, type, actionResult, actionType, params, caretRow, caretCol)
{
var scc = action.snippetCompleteCache;
if ( ac.chap.ACTION_LISTENER_BEFORE == type && !scc.firstInitialized )
{
// before action listener
// check if we are still in the tabstop range
// var offset = component.char_map[caretRow].substr()
// console.log('activeTabStopRange: %o', scc.activeTabStopRange);
if ( caretRow < scc.activeTabStopRange[0] || caretRow > scc.activeTabStopRange[2] || caretCol < scc.activeTabStopRange[1] || caretCol > scc.activeTabStopRange[3] )
{
// out of range, canceling whole snippet logic
component.removeActionListener(scc.callbackIndex);
component.removeSelection();
delete action.snippetCompleteCache;
// console.log('CANCELED');
return;
}
// console.log('before: %s - [%s,%s]', actionType, caretRow, caretCol);
}
else
{
// after action listener
if ( scc.firstInitialized )
{
scc.firstInitialized = false;
var tabstop = scc.tabstops[scc.activeTabStopIndex];
caretCol -= tabstop[1].length;
var code_rows = tabstop[1].split('\n');
var num_code_rows = code_rows.length;
var to_caret_row = caretRow + num_code_rows - 1;
var to_caret_col = (to_caret_row == caretRow ? caretCol : 0) + code_rows[num_code_rows-1].length;
scc.activeTabStopRange = [caretRow, caretCol, to_caret_row, to_caret_col];
scc.stopMarker = component.char_map[to_caret_row].substr(to_caret_col);
// creating list of nested tabstops
for ( var i in scc.tabstops )
{
if ( i == scc.activeTabStopIndex )
{
continue;
}
var c_tabstop = scc.tabstops[i];
if ( c_tabstop[2] >= tabstop[2] && (c_tabstop[2] + c_tabstop[3] <= tabstop[2] + tabstop[3]) )
{
scc.activeTabStopNested[i] = true;
}
}
if ( 'mi' != tabstop[0] )
{
scc.activeTabStopContent = tabstop[1];
}
scc.firstRealRun = false;
// action.snippetCompletePostInit(component, caretRow, caretCol);
// console.log('firstRealRun: %o', scc.activeTabStopRange);
}
else
{
// console.log('next: %o', scc.activeTabStopRange);
// adjust the range by finding the stop marker
var n = component.char_map.length;
var i = scc.activeTabStopRange[0];
var found = false;
var max_iter = 50;
// var offset_range = [scc.activeTabStopRange[2], scc.activeTabStopRange[3]];
var new_content = '';
var old_content = scc.activeTabStopContent;
while ( i active_offset )
{
if ( scc.activeTabStopNested[i] )
{
// nested
delete scc.tabstops[i];
}
else
{
tabstop[2] += offset;
// console.log('ADJUSTING: #%s by %s, new: %s', i, offset, tabstop[2]);
}
}
}
}
}
// console.log('after %s(%s, %s) : %o', actionType, caretRow, caretCol, scc.activeTabStopRange);
}
}
ac.chap.KeyMap.prototype.compile = function(source)
{
/* example:
KEY: -13+shift
selection(add:true)
caret(move:'up')
KEY: -27
caret(move:'row_end')
...
..
.
*/
var rows = source.split('\n');
var n = rows.length;
var re_definition = /^KEY\:\s*[-\d]*[\+\w\s]*$/;
var re_chain = /^[^\(]*\(.*\)\s*$/;
var src = '';
var chain = [];
var last_key_code = null;
for ( var i=0; i)/i, 0, ac.chap.CHUNK_OPERATOR],
[/(\(|\)|\[|\]|\{|\})/i, 0, ac.chap.CHUNK_PARENTHESIS]
];
this.wordDelimiter = /[\w\.\d]/;
this.indentIgnoreMarker = /[\.]/;
}
ac.chap.lang = {};
/* loader stuff - you are free to modify as needed */
// !! Make sure, bundle_*.js is loaded prior launching this function - the bundle defines ac.chap.langEAmy, EAmyJavaScript etc.
function showEditor(templateNode)
{
var source = templateNode.value;
templateNode = $(templateNode);
var w = templateNode.w();
var h = templateNode.h();
var node = templateNode.p().ib($$(), templateNode).w(w).h(h);
templateNode.d(false);
var language = ac.chap.lang.JavaScript;
var keymap = ac.chap.keymap.EAmyJavaScript;
var instance = $new(ac.chap.Window, {language:ac.chap.lang.EAmy, keymap:ac.chap.Keymap});
instance.addView(node, {theme:ac.chap.theme.EAmy, rowHeight:11, colWidth:7, wordWrap:true, tabelator:' '});
instance.show();
instance.setSnippets(eamy.snippets);
instance.keymap.importSnippets(eamy.snippets);
instance.edit(source);
eamy.instances.push(instance);
}
// !! Remove from here and include in your section if you want.
// document.write('');
// Performed upon loading the page. You are free to remove it and call the showEditor() (or modified version of it) in order to launch the editing component. Code of the showEditor should give you enough clue.
$__tune.event.addListener(self, 'load', function(evt)
{
// this is basically a search for any