Skip to content
This repository was archived by the owner on Sep 8, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,28 @@ myAppModule.controller('MyController', [ '$scope', function($scope) {

To handle other options you'll have to use a direct access to the Ace created instance (see [below](#ace-instance-direct-access)).

## Advanced Options

You can specify advanced options and even `require` options in the directive, as well. For this example, you
will have to include the `ext-language_tools.js` file from the ace source code.

This will copy the UI.Ace files into a `bower_components` folder, along with its dependencies. Load the script files in your application:

```html
<script type="text/javascript" src="bower_components/ace-builds/src-min-noconflict/ext-language_tools.js"></script>
```

```html
<div ui-ace="{
require: ['ace/ext/language_tools'],
advanced: {
enableSnippets: true,
enableBasicAutocompletion: true,
enableLiveAutocompletion: true
}
}"></div>
```

### Working with ng-model

The ui-ace directive plays nicely with ng-model.
Expand Down
17 changes: 16 additions & 1 deletion src/ui-ace.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ angular.module('ui.ace', [])
* @param {object} opts Options to be set
*/
var setOptions = function(acee, session, opts) {

// 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);
Expand Down Expand Up @@ -84,6 +89,16 @@ angular.module('ui.ace', [])
session.setOption('firstLineNumber', opts.firstLineNumber());
}
}

// advanced options
if (angular.isDefined(opts.advanced)) {
for (var key in opts.advanced) {
// create a javascript object with the key and value
var obj = { name: key, value: opts.advanced[key] };
// try to assign the option to the ace editor
acee.setOption(obj.name, obj.value);
}
}
};

return {
Expand Down
85 changes: 83 additions & 2 deletions test/ace.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ describe('uiAce', function () {
beforeEach(inject(function (uiAceConfig) {
uiConfig = uiAceConfig;
uiConfig.ace = {showGutter: false};

}));

// inject in angular constructs. Injector knows about leading/trailing underscores and does the right thing
Expand All @@ -22,6 +21,89 @@ describe('uiAce', function () {
uiConfig = {};
});

describe('behavior', function () {
var _ace;

beforeEach(function () {
_ace = window.ace;
spyOn(window.ace, 'require');
});
it('should not call window.ace.require if there is no "require" option', function () {
$compile('<div ui-ace>')(scope);
expect(_ace.require).not.toHaveBeenCalled();
});
});

describe('behavior', function () {
var _ace;

beforeEach(function () {
_ace = window.ace;
spyOn(window.ace, 'require');
});
it('should call "window.ace.require" for each option in "require"', function () {
$compile('<div ui-ace=\'{ require: ["ace/ext/language_tools", "ace/ext/static_highlight"]}\'>')(scope);
expect(_ace.require).toHaveBeenCalled();
expect(_ace.require.callCount).toEqual(2);
});
});

describe('behavior', function () {
var _ace;

beforeEach(function () {
var aceEditFunction = window.ace.edit;
spyOn(window.ace, 'edit').andCallFake(function () {
_ace = aceEditFunction.apply(this, arguments);
return _ace;
});
});
it('should not call "setOption" if no "advanced" options are given.', function () {
$compile('<div ui-ace>')(scope);
var session = _ace.getSession();
spyOn(session, 'setOption');
expect(session.setOption).not.toHaveBeenCalled();
});
});

describe('behavior', function () {
var _ace;

beforeEach(function () {
var aceEditFunction = window.ace.edit;
spyOn(window.ace, 'edit').andCallFake(function () {
_ace = aceEditFunction.apply(this, arguments);
return _ace;
});
});
it('Given advanced option is null if not defined.', function () {
$compile('<div ui-ace>')(scope);
var session = _ace.getSession();
spyOn(session, 'getOption');
expect(session.getOption).toBeDefined();
expect(session.getOption('enableSnippets')).not.toBeDefined();
});
});

describe('behavior', function () {
var _ace;

beforeEach(function () {
var aceEditFunction = window.ace.edit;
spyOn(window.ace, 'edit').andCallFake(function () {
_ace = aceEditFunction.apply(this, arguments);
return _ace;
});
});
it('given advanced options are properly defined.', function () {
$compile('<div ui-ace=\'{ advanced: { enableSnippets: true } }\'>')(scope);
var session = _ace.getSession();
spyOn(session, 'getOption');
expect(session.getOption).toBeDefined();
expect(session.getOption('enableSnippets')).not.toBe(null);
});
});

describe('behavior', function () {

it('should not throw an error when window.ace is defined', function () {
Expand All @@ -38,7 +120,6 @@ describe('uiAce', function () {
$compile('<div ui-ace ng-model="foo">')(scope);
expect(scope.$watch).toHaveBeenCalled();
});

});

describe('instance', function () {
Expand Down