favicon_package
fonts
keycloak-resources
resources
css
img
resources_common
img
lib
angular
filesaver
fileupload
ui-ace
min
ace.js
mode-javascript.js
theme-github.js
ui-ace.js
ui-ace.min.js
worker-javascript.js
zocial
node_modules
package-lock.json
package.json
README.txt
static
1093.60429de4.iframe.bundle.js
127.500e8d19.iframe.bundle.js
1377.7390f9ad.iframe.bundle.js
1413.dfe52a3f.iframe.bundle.js
1433.d55084fa.iframe.bundle.js
1472.12680f26.iframe.bundle.js
161.3e0db7e5.iframe.bundle.js
1730.5b971e44.iframe.bundle.js
1793.92b4f010.iframe.bundle.js
1883.fcab8581.iframe.bundle.js
229.a3edc932cd36e0f6e55f.manager.bundle.js
2372.223a728e.iframe.bundle.js
2410.2df18c64.iframe.bundle.js
2551.31c9ba53.iframe.bundle.js
2559.1feb0b98.iframe.bundle.js
2683.ad4b7d28.iframe.bundle.js
2683.ad4b7d28.iframe.bundle.js.LICENSE.txt
2807.10c2ef7b.iframe.bundle.js
2866.023b69e6.iframe.bundle.js
2887.55398011.iframe.bundle.js
2897.f55cc16b.iframe.bundle.js
2897.f55cc16b.iframe.bundle.js.LICENSE.txt
295.f4d5c04b864138f57a82.manager.bundle.js
2954.5df6b776.iframe.bundle.js
3148.8c440f6d.iframe.bundle.js
3284.4a24c1f3.iframe.bundle.js
3304.fe252a8f.iframe.bundle.js
3612.4fc69242.iframe.bundle.js
3644.d0a7b38f.iframe.bundle.js
3744.76fc4ed3.iframe.bundle.js
3765.2608ff8d.iframe.bundle.js
3778.67eaf6b2.iframe.bundle.js
3900.a01e955a.iframe.bundle.js
3917.d8e9cbae.iframe.bundle.js
3946.da1ae0b6.iframe.bundle.js
3972.5f23f0d8.iframe.bundle.js
4040.893ff37a.iframe.bundle.js
409.24acde94.iframe.bundle.js
4119.c9e70457.iframe.bundle.js
4142.6f96b15c.iframe.bundle.js
4174.98d14cf5.iframe.bundle.js
4211.3396acbd.iframe.bundle.js
4247.40a68100.iframe.bundle.js
4290.3df66729.iframe.bundle.js
4486.d259a160.iframe.bundle.js
4660.c814c862.iframe.bundle.js
487.9fc73fb0.iframe.bundle.js
4950.8972af39.iframe.bundle.js
500.49445e49.iframe.bundle.js
5013.232246c1.iframe.bundle.js
5025.b4819ec6.iframe.bundle.js
5025.b4819ec6.iframe.bundle.js.LICENSE.txt
5051.7ef3c2fe.iframe.bundle.js
5051.7ef3c2fe.iframe.bundle.js.LICENSE.txt
51.a8a99f9e78fc313d0262.manager.bundle.js
51.a8a99f9e78fc313d0262.manager.bundle.js.LICENSE.txt
5119.df2eae77.iframe.bundle.js
5229.565594db.iframe.bundle.js
551.67eb16aa5baf67eaae71.manager.bundle.js
5583.37e40d5f.iframe.bundle.js
5583.37e40d5f.iframe.bundle.js.LICENSE.txt
5753.2ac6c3d6.iframe.bundle.js
5935.7426907f.iframe.bundle.js
5965.6935f8ae.iframe.bundle.js
5975.aa2c06bb.iframe.bundle.js
6056.80ab56b6.iframe.bundle.js
6120.1e1e5f88.iframe.bundle.js
6152.f934a0a4.iframe.bundle.js
6213.8031b1b6.iframe.bundle.js
6344.50f830ec.iframe.bundle.js
6490.91f43ccb.iframe.bundle.js
650.15cc3462.iframe.bundle.js
650.15cc3462.iframe.bundle.js.LICENSE.txt
651.5ff1f96e.iframe.bundle.js
6701.2f6f5aa8.iframe.bundle.js
6726.fbe71dc5.iframe.bundle.js
7087.a97cd9a6.iframe.bundle.js
7146.ef8490f2.iframe.bundle.js
7273.c5ec45e8.iframe.bundle.js
745.457d6663.iframe.bundle.js
7765.4cce873f.iframe.bundle.js
7799.a3c4a09c.iframe.bundle.js
7851.ebfaa3e2.iframe.bundle.js
787.65ae14ea.iframe.bundle.js
7890.e36a25a1.iframe.bundle.js
7901.be52cda8.iframe.bundle.js
8060.49b3c71c.iframe.bundle.js
807.a2a908ed7f68724ba5f8.manager.bundle.js
807.a2a908ed7f68724ba5f8.manager.bundle.js.LICENSE.txt
826.69755296b67440263ca4.manager.bundle.js
826.69755296b67440263ca4.manager.bundle.js.LICENSE.txt
8470.efdb2489.iframe.bundle.js
897.dcd0c98d13513b1494b4.manager.bundle.js
897.dcd0c98d13513b1494b4.manager.bundle.js.LICENSE.txt
9061.bdd52f4d.iframe.bundle.js
9096.c212d2a8.iframe.bundle.js
9115.52d043b4.iframe.bundle.js
9115.52d043b4.iframe.bundle.js.LICENSE.txt
935.cbaac73deea7306bafa1.manager.bundle.js
9749.4c5ddc9f.iframe.bundle.js
9782.8743a5c2.iframe.bundle.js
980.f1b0837f.iframe.bundle.js
9807.7e2f822f.iframe.bundle.js
9807.7e2f822f.iframe.bundle.js.LICENSE.txt
9980.5fa141fd.iframe.bundle.js
CNAME
favicon.ico
iframe.html
index.html
logo.png
main.2f21d48492887a731906.manager.bundle.js
main.3d096d73.iframe.bundle.js
main.3d096d73.iframe.bundle.js.LICENSE.txt
preview.png
project.json
runtime~main.5acabe14b3900323beb2.manager.bundle.js
runtime~main.81562a25.iframe.bundle.js
329 lines
10 KiB
JavaScript
329 lines
10 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* Binds a ACE Editor widget
|
|
*/
|
|
angular.module('ui.ace', [])
|
|
.constant('uiAceConfig', {})
|
|
.directive('uiAce', ['uiAceConfig', function (uiAceConfig) {
|
|
|
|
if (angular.isUndefined(window.ace)) {
|
|
throw new Error('ui-ace need ace to work... (o rly?)');
|
|
}
|
|
|
|
/**
|
|
* Sets editor options such as the wrapping mode or the syntax checker.
|
|
*
|
|
* The supported options are:
|
|
*
|
|
* <ul>
|
|
* <li>showGutter</li>
|
|
* <li>useWrapMode</li>
|
|
* <li>onLoad</li>
|
|
* <li>theme</li>
|
|
* <li>mode</li>
|
|
* </ul>
|
|
*
|
|
* @param acee
|
|
* @param session ACE editor session
|
|
* @param {object} opts Options to be set
|
|
*/
|
|
var setOptions = function(acee, session, opts) {
|
|
|
|
// sets the ace worker path, if running from concatenated
|
|
// or minified source
|
|
if (angular.isDefined(opts.workerPath)) {
|
|
var config = window.ace.require('ace/config');
|
|
config.set('workerPath', opts.workerPath);
|
|
}
|
|
// ace requires loading
|
|
if (angular.isDefined(opts.require)) {
|
|
opts.require.forEach(function (n) {
|
|
window.ace.require(n);
|
|
});
|
|
}
|
|
// Boolean options
|
|
if (angular.isDefined(opts.showGutter)) {
|
|
acee.renderer.setShowGutter(opts.showGutter);
|
|
}
|
|
if (angular.isDefined(opts.useWrapMode)) {
|
|
session.setUseWrapMode(opts.useWrapMode);
|
|
}
|
|
if (angular.isDefined(opts.showInvisibles)) {
|
|
acee.renderer.setShowInvisibles(opts.showInvisibles);
|
|
}
|
|
if (angular.isDefined(opts.showIndentGuides)) {
|
|
acee.renderer.setDisplayIndentGuides(opts.showIndentGuides);
|
|
}
|
|
if (angular.isDefined(opts.useSoftTabs)) {
|
|
session.setUseSoftTabs(opts.useSoftTabs);
|
|
}
|
|
if (angular.isDefined(opts.showPrintMargin)) {
|
|
acee.setShowPrintMargin(opts.showPrintMargin);
|
|
}
|
|
|
|
// commands
|
|
if (angular.isDefined(opts.disableSearch) && opts.disableSearch) {
|
|
acee.commands.addCommands([
|
|
{
|
|
name: 'unfind',
|
|
bindKey: {
|
|
win: 'Ctrl-F',
|
|
mac: 'Command-F'
|
|
},
|
|
exec: function () {
|
|
return false;
|
|
},
|
|
readOnly: true
|
|
}
|
|
]);
|
|
}
|
|
|
|
// Basic options
|
|
if (angular.isString(opts.theme)) {
|
|
acee.setTheme('ace/theme/' + opts.theme);
|
|
}
|
|
if (angular.isString(opts.mode)) {
|
|
session.setMode('ace/mode/' + opts.mode);
|
|
}
|
|
// Advanced options
|
|
if (angular.isDefined(opts.firstLineNumber)) {
|
|
if (angular.isNumber(opts.firstLineNumber)) {
|
|
session.setOption('firstLineNumber', opts.firstLineNumber);
|
|
} else if (angular.isFunction(opts.firstLineNumber)) {
|
|
session.setOption('firstLineNumber', opts.firstLineNumber());
|
|
}
|
|
}
|
|
|
|
// advanced options
|
|
var key, obj;
|
|
if (angular.isDefined(opts.advanced)) {
|
|
for (key in opts.advanced) {
|
|
// create a javascript object with the key and value
|
|
obj = { name: key, value: opts.advanced[key] };
|
|
// try to assign the option to the ace editor
|
|
acee.setOption(obj.name, obj.value);
|
|
}
|
|
}
|
|
|
|
// advanced options for the renderer
|
|
if (angular.isDefined(opts.rendererOptions)) {
|
|
for (key in opts.rendererOptions) {
|
|
// create a javascript object with the key and value
|
|
obj = { name: key, value: opts.rendererOptions[key] };
|
|
// try to assign the option to the ace editor
|
|
acee.renderer.setOption(obj.name, obj.value);
|
|
}
|
|
}
|
|
|
|
// onLoad callbacks
|
|
angular.forEach(opts.callbacks, function (cb) {
|
|
if (angular.isFunction(cb)) {
|
|
cb(acee);
|
|
}
|
|
});
|
|
};
|
|
|
|
return {
|
|
restrict: 'EA',
|
|
require: '?ngModel',
|
|
link: function (scope, elm, attrs, ngModel) {
|
|
|
|
/**
|
|
* Corresponds the uiAceConfig ACE configuration.
|
|
* @type object
|
|
*/
|
|
var options = uiAceConfig.ace || {};
|
|
|
|
/**
|
|
* uiAceConfig merged with user options via json in attribute or data binding
|
|
* @type object
|
|
*/
|
|
var opts = angular.extend({}, options, scope.$eval(attrs.uiAce));
|
|
|
|
/**
|
|
* ACE editor
|
|
* @type object
|
|
*/
|
|
var acee = window.ace.edit(elm[0]);
|
|
|
|
/**
|
|
* ACE editor session.
|
|
* @type object
|
|
* @see [EditSession]{@link http://ace.c9.io/#nav=api&api=edit_session}
|
|
*/
|
|
var session = acee.getSession();
|
|
|
|
/**
|
|
* Reference to a change listener created by the listener factory.
|
|
* @function
|
|
* @see listenerFactory.onChange
|
|
*/
|
|
var onChangeListener;
|
|
|
|
/**
|
|
* Reference to a blur listener created by the listener factory.
|
|
* @function
|
|
* @see listenerFactory.onBlur
|
|
*/
|
|
var onBlurListener;
|
|
|
|
/**
|
|
* Calls a callback by checking its existing. The argument list
|
|
* is variable and thus this function is relying on the arguments
|
|
* object.
|
|
* @throws {Error} If the callback isn't a function
|
|
*/
|
|
var executeUserCallback = function () {
|
|
|
|
/**
|
|
* The callback function grabbed from the array-like arguments
|
|
* object. The first argument should always be the callback.
|
|
*
|
|
* @see [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments}
|
|
* @type {*}
|
|
*/
|
|
var callback = arguments[0];
|
|
|
|
/**
|
|
* Arguments to be passed to the callback. These are taken
|
|
* from the array-like arguments object. The first argument
|
|
* is stripped because that should be the callback function.
|
|
*
|
|
* @see [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments}
|
|
* @type {Array}
|
|
*/
|
|
var args = Array.prototype.slice.call(arguments, 1);
|
|
|
|
if (angular.isDefined(callback)) {
|
|
scope.$evalAsync(function () {
|
|
if (angular.isFunction(callback)) {
|
|
callback(args);
|
|
} else {
|
|
throw new Error('ui-ace use a function as callback.');
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Listener factory. Until now only change listeners can be created.
|
|
* @type object
|
|
*/
|
|
var listenerFactory = {
|
|
/**
|
|
* Creates a change listener which propagates the change event
|
|
* and the editor session to the callback from the user option
|
|
* onChange. It might be exchanged during runtime, if this
|
|
* happens the old listener will be unbound.
|
|
*
|
|
* @param callback callback function defined in the user options
|
|
* @see onChangeListener
|
|
*/
|
|
onChange: function (callback) {
|
|
return function (e) {
|
|
var newValue = session.getValue();
|
|
|
|
if (ngModel && newValue !== ngModel.$viewValue &&
|
|
// HACK make sure to only trigger the apply outside of the
|
|
// digest loop 'cause ACE is actually using this callback
|
|
// for any text transformation !
|
|
!scope.$$phase && !scope.$root.$$phase) {
|
|
scope.$evalAsync(function () {
|
|
ngModel.$setViewValue(newValue);
|
|
});
|
|
}
|
|
|
|
executeUserCallback(callback, e, acee);
|
|
};
|
|
},
|
|
/**
|
|
* Creates a blur listener which propagates the editor session
|
|
* to the callback from the user option onBlur. It might be
|
|
* exchanged during runtime, if this happens the old listener
|
|
* will be unbound.
|
|
*
|
|
* @param callback callback function defined in the user options
|
|
* @see onBlurListener
|
|
*/
|
|
onBlur: function (callback) {
|
|
return function () {
|
|
executeUserCallback(callback, acee);
|
|
};
|
|
}
|
|
};
|
|
|
|
attrs.$observe('readonly', function (value) {
|
|
acee.setReadOnly(!!value || value === '');
|
|
});
|
|
|
|
// Value Blind
|
|
if (ngModel) {
|
|
ngModel.$formatters.push(function (value) {
|
|
if (angular.isUndefined(value) || value === null) {
|
|
return '';
|
|
}
|
|
else if (angular.isObject(value) || angular.isArray(value)) {
|
|
throw new Error('ui-ace cannot use an object or an array as a model');
|
|
}
|
|
return value;
|
|
});
|
|
|
|
ngModel.$render = function () {
|
|
session.setValue(ngModel.$viewValue);
|
|
};
|
|
}
|
|
|
|
// Listen for option updates
|
|
var updateOptions = function (current, previous) {
|
|
if (current === previous) return;
|
|
opts = angular.extend({}, options, scope.$eval(attrs.uiAce));
|
|
|
|
opts.callbacks = [ opts.onLoad ];
|
|
if (opts.onLoad !== options.onLoad) {
|
|
// also call the global onLoad handler
|
|
opts.callbacks.unshift(options.onLoad);
|
|
}
|
|
|
|
// EVENTS
|
|
|
|
// unbind old change listener
|
|
session.removeListener('change', onChangeListener);
|
|
|
|
// bind new change listener
|
|
onChangeListener = listenerFactory.onChange(opts.onChange);
|
|
session.on('change', onChangeListener);
|
|
|
|
// unbind old blur listener
|
|
//session.removeListener('blur', onBlurListener);
|
|
acee.removeListener('blur', onBlurListener);
|
|
|
|
// bind new blur listener
|
|
onBlurListener = listenerFactory.onBlur(opts.onBlur);
|
|
acee.on('blur', onBlurListener);
|
|
|
|
setOptions(acee, session, opts);
|
|
};
|
|
|
|
scope.$watch(attrs.uiAce, updateOptions, /* deep watch */ true);
|
|
|
|
// set the options here, even if we try to watch later, if this
|
|
// line is missing things go wrong (and the tests will also fail)
|
|
updateOptions(options);
|
|
|
|
elm.on('$destroy', function () {
|
|
acee.session.$stopWorker();
|
|
acee.destroy();
|
|
});
|
|
|
|
scope.$watch(function() {
|
|
return [elm[0].offsetWidth, elm[0].offsetHeight];
|
|
}, function() {
|
|
acee.resize();
|
|
acee.renderer.updateFull();
|
|
}, true);
|
|
|
|
}
|
|
};
|
|
}]);
|