Skip to content

Commit 03fff7d

Browse files
committed
Add Event Hooks Callback and external fn calls
Add Event Hooks Callback Also make each Markdown Editor object available through $rootScope.markdownEditorObjects[editorName]
1 parent 9b7f664 commit 03fff7d

7 files changed

+187
-44
lines changed

bower.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular-markdown-editor-ghiscoding",
3-
"version": "1.0.9",
3+
"version": "1.1.0",
44
"author": "Ghislain B.",
55
"description": "Angular Markdown Editor, all-in-one Markdown Editor and Preview",
66
"main": [

example/app.js

+31-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ angular.module('example-app', ['hc.marked', 'hljs', 'angular-markdown-editor'])
2222
tabReplace: ' '
2323
});
2424
}])
25-
.controller("MainController", ["$scope", "marked", function MarkdownController($scope, marked) {
26-
$scope.markdown = "*This* **is** [markdown](https://daringfireball.net/projects/markdown/)\n and `{{ 1 + 2 }}` = {{ 1 + 2 }}";
25+
.controller("MainController", ["$rootScope", "$scope", "marked", function MarkdownController($rootScope, $scope, marked) {
26+
$scope.editor1 = "*This* **is** [markdown](https://daringfireball.net/projects/markdown/)\n and `{{ 1 + 2 }}` = {{ 1 + 2 }}";
2727
$scope.markdownService = marked('#TEST');
2828

2929
// --
@@ -32,4 +32,33 @@ angular.module('example-app', ['hc.marked', 'hljs', 'angular-markdown-editor'])
3232
vm.convertedMarkdown = marked(vm.markdown);
3333
}
3434

35+
/**
36+
* For some convenience, Angular-Markdown-Editor Directive also save each Markdown Editor inside $rootScope
37+
* Each of editor object are available through their $rootScope.markdownEditorObjects[editorName]
38+
*
39+
* Example: <textarea name="editor1" markdown-editor="{'iconlibrary': 'fa'}"></textarea>
40+
* We would then call our object through $rootScope.markdownEditorObjects.editor1
41+
*/
42+
$scope.fullScreenPreview = function() {
43+
$rootScope.markdownEditorObjects.editor1.showPreview();
44+
$rootScope.markdownEditorObjects.editor1.setFullscreen(true);
45+
}
46+
47+
/** Markdown event hook onFullscreen, in this example we will automatically show the result preview when going in full screen
48+
* the argument (e) is the actual Markdown object returned which help call any of API functions defined in Markdown Editor
49+
* For a list of API functions take a look on official demo site http://www.codingdrama.com/bootstrap-markdown/
50+
* @param object e: Markdown Editor object
51+
*/
52+
$scope.onFullScreenCallback = function(e) {
53+
e.showPreview();
54+
}
55+
56+
/** After exiting from full screen, let's go back to editor mode (which mean hide the preview)
57+
* NOTE: If you want this one to work, you will have to manually download the JS file, not sure why but they haven't released any versions in a while
58+
* https://github.com/toopay/bootstrap-markdown/tree/master/js
59+
*/
60+
$scope.onFullScreenExitCallback = function(e) {
61+
e.hidePreview();
62+
}
63+
3564
}]);

example/index.html

+26-12
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323

2424
<!-- your ng-app file -->
2525
<script type="text/javascript" src="../src/angular-markdown-editor.js"></script>
26-
<script type="text/javascript" src="../src/angular-markdown-editor-locale.js"></script>
2726
<script type="text/javascript" src="app.js"></script>
27+
28+
<!-- You could also load any available locale -->
29+
<script type="text/javascript" src="../node_modules/bootstrap-markdown/locale/bootstrap-markdown.fr.js"></script>
2830
</head>
2931

3032
<body ng-app="example-app" ng-controller="MainController">
@@ -43,20 +45,32 @@ <h1>Angular Markdown Editor</h1>
4345

4446
<hr/>
4547

48+
<div>
49+
External Markdown Editor API Calls with `$rootScope.markdownEditorObjects`
50+
<br/>
51+
<button class="btn btn-info" ng-click="fullScreenPreview()">Full Screen Preview</button>
52+
</div>
53+
<hr/>
4654
<div class="row">
47-
<div class="col-md-12 col-lg-6">
48-
<div class="form-group">
49-
<label for="comment">Live Markdown with <a href="http://www.codingdrama.com/bootstrap-markdown/">Bootstrap-Markdown Editor</a>:</label>
50-
<textarea name="content" class="content-box" markdown-editor="{'iconlibrary': 'fa', addExtraButtons: true, resize: 'vertical'}" rows="10" ng-model="markdown"></textarea>
51-
</div>
55+
<div class="col-md-12 col-lg-6">
56+
<div class="form-group">
57+
<label for="comment">Live Markdown with <a href="http://www.codingdrama.com/bootstrap-markdown/">Bootstrap-Markdown Editor</a>:</label>
58+
<textarea name="editor1" class="content-box"
59+
ng-model="editor1"
60+
markdown-editor="{'iconlibrary': 'fa', addExtraButtons: true, resize: 'vertical'}"
61+
on-fullscreen="onFullScreenCallback()"
62+
on-fullscreen-exit="onFullScreenExitCallback()"
63+
rows="10" >
64+
</textarea>
5265
</div>
53-
<div class="col-md-12 col-lg-6 fill">
54-
<div class="form-group">
55-
<label for="comment">Preview Result:</label>
56-
<div marked="markdown" class="markdown outline" style="padding: 20px">
57-
</div>
58-
</div>
66+
</div>
67+
<div class="col-md-12 col-lg-6 fill">
68+
<div class="form-group">
69+
<label for="comment">Preview Result:</label>
70+
<div marked="editor1" class="markdown outline" style="padding: 20px">
71+
</div>
5972
</div>
73+
</div>
6074
</div>
6175

6276
<hr/>

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "angular-markdown-editor",
3-
"version": "1.0.9",
3+
"version": "1.1.0",
44
"author": "Ghislain B.",
55
"description": "Angular Markdown Editor, all-in-one Markdown Editor and Preview",
66
"main": "app.js",

readme.md

+68-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Angular Markdown Editor (Directive)
2-
`1.0.9`
2+
`1.1.0`
33

44
## What do we have?
55
In this package you a few libraries and tools to make a more convenient "all in one" WYSIWYG Markdown Editor with preview. All of that with a simple AngularJS Directive call. I plan to use this mainly for online documentation but it could be useful for many other reasons (doc, blog, etc...). Also planning on adding a 1-click button for simple Copy+Paste to email.
@@ -57,8 +57,8 @@ _NOTE: Unfortunately, the "highlight.js" npm module doesn't seem to have proper
5757
<script type="text/javascript" src="../node_modules/angular-highlightjs/src/angular-highlightjs.js"></script>
5858
<script type="text/javascript" src="../node_modules/angular-markdown-editor/src/angular-markdown-editor.js"></script>
5959

60-
<!-- you can add your own locale with this file, if you had new locale please make a PR -->
61-
<script type="text/javascript" src="../node_modules/angular-markdown-editor/src/angular-markdown-editor-locale.js"></script>
60+
<!-- You could also load any available locale, look on their website https://github.com/toopay/bootstrap-markdown/tree/master/locale -->
61+
<script type="text/javascript" src="../node_modules/bootstrap-markdown/locale/bootstrap-markdown.fr.js"></script>
6262
```
6363

6464
### Inside the HTML
@@ -87,5 +87,70 @@ I really thought that some buttons were missing to go a great job (~~Strikethrou
8787
<textarea markdown-editor="{addExtraButtons: true, 'iconlibrary': 'fa'}"...
8888
```
8989

90+
### Event Hooks
91+
###### starting with Angular-Markdown-Editor version 1.1.0
92+
You have access to all the Bootstrap Markdown Editor available events/hooks directly in the directive
93+
94+
_NOTE: It seems that Bootstrap Markdown Editor haven't releease any versions in a while but a lot of commits are still happening. If you want all the Events/Hooks to work, you should manually download the [Bootstrap Markdown Editor.js](https://github.com/toopay/bootstrap-markdown/tree/master/js) file yourself._
95+
96+
- onPreview
97+
- onPreviewEnd
98+
- onSave
99+
- onBlur
100+
- onFocus
101+
- onFullscreen
102+
- onFullscreenExit
103+
- onChange
104+
- onSelect
105+
- onShow
106+
107+
For example HTML
108+
```html
109+
<textarea name="editor1" class="content-box"
110+
ng-model="editor1"
111+
markdown-editor="{'iconlibrary': 'fa', addExtraButtons: true, resize: 'vertical'}"
112+
on-fullscreen="onFullScreenCallback()"
113+
on-fullscreen-exit="onFullScreenExitCallback()"
114+
rows="10" >
115+
</textarea>
116+
```
117+
Controller
118+
You can call any API functions defined in Markdown Editor, take a look at their API section [Bootstrap Markdown Editor - API functions](http://www.codingdrama.com/bootstrap-markdown/)
119+
120+
```javascript
121+
/** Markdown event hook onFullscreen, in this example we will automatically show the result preview when going in full screen
122+
* the argument (e) is the actual Markdown object returned which help call any of API functions defined in Markdown Editor
123+
* @param object e: Markdown Editor object
124+
*/
125+
$scope.onFullScreenCallback = function(e) {
126+
e.showPreview();
127+
}
128+
```
129+
130+
### External function calls through $rootScope.markdownEditorObjects
131+
###### starting with Angular-Markdown-Editor version 1.1.0
132+
For conveniencies and for possible external function calls, Angular-Markdown-Editor saves each of the Markdown Editors inside `$rootScope.markdownEditorObjects[editorName]`. This basically means that on any define editor, we could call any of the [Bootstrap Markdown Editor - API functions](http://www.codingdrama.com/bootstrap-markdown/).
133+
This varies with previous subject of (Event Hooks), since using the `$rootScope.markdownEditorObjects` can be called at any and makes perfect for example on a function attached to a button (for example an external button for a Full Screen Preview as shown below).
134+
135+
For example HTML
136+
```html
137+
<button class="btn btn-info" ng-click="fullScreenPreview()">Full Screen Preview</button>
138+
```
139+
140+
Controller
141+
```javascript
142+
/**
143+
* For some convenience, Angular-Markdown-Editor Directive also save each Markdown Editor inside $rootScope
144+
* Each of editor object are available through their $rootScope.markdownEditorObjects[editorName]
145+
*
146+
* Example: <textarea name="editor1" markdown-editor="{'iconlibrary': 'fa'}"></textarea>
147+
* We would then call our object through $rootScope.markdownEditorObjects.editor1
148+
*/
149+
$scope.fullScreenPreview = function() {
150+
$rootScope.markdownEditorObjects.editor1.showPreview();
151+
$rootScope.markdownEditorObjects.editor1.setFullscreen(true);
152+
}
153+
```
154+
90155
## Preview
91156
![Login Page](https://raw.githubusercontent.com/ghiscoding/angular-markdown-editor/master/images/scrshot_preview.png)

src/angular-markdown-editor-locale.js

-20
This file was deleted.

src/angular-markdown-editor.js

+60-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
angular
22
.module('angular-markdown-editor', [])
3-
.directive('markdownEditor', ['$parse', function(parse) {
3+
.directive('markdownEditor', ['$rootScope', function ($rootScope) {
44
return {
55
restrict: 'A',
66
require: 'ngModel',
@@ -31,10 +31,36 @@ angular
3131
enableDropDataUri: options.enableDropDataUri || false,
3232
showButtons: options.showButtons || null,
3333
additionalButtons: options.additionalButtons || (options.addExtraButtons ? addNewButtons() : []),
34-
onChange: function(event) {
35-
// When a change occurs, we need to update scope in case the user clicked one of the plugin buttons
36-
// (which isn't the same as a keydown event that angular would listen for).
37-
ngModel.$setViewValue(event.getContent());
34+
35+
//-- Events/Hooks --
36+
// each of them are defined as callback available in the directive
37+
// example: <textarea markdown-editor="{'iconlibrary': 'fa'}" on-fullscreen-exit="vm.exitFullScreenCallback()"></textarea>
38+
// NOTE: If you want this one to work, you will have to manually download the JS file, not sure why but they haven't released any versions in a while
39+
// https://github.com/toopay/bootstrap-markdown/tree/master/js
40+
onPreview: function (e) { runScopeFunction(scope, attrs.onPreview, e); },
41+
onPreviewEnd: function (e) { runScopeFunction(scope, attrs.onPreviewEnd, e); },
42+
onSave: function (e) { runScopeFunction(scope, attrs.onSave, e); },
43+
onBlur: function (e) { runScopeFunction(scope, attrs.onBlur, e); },
44+
onFocus: function (e) { runScopeFunction(scope, attrs.onFocus, e); },
45+
onFullscreen: function (e) { runScopeFunction(scope, attrs.onFullscreen, e); },
46+
onSelect: function (e) { runScopeFunction(scope, attrs.onSelect, e); },
47+
onFullscreenExit: function (e) { runScopeFunction(scope, attrs.onFullscreenExit, e); },
48+
onChange: function(e) {
49+
// When a change occurs, we need to update scope in case the user clicked one of the plugin buttons
50+
// (which isn't the same as a keydown event that angular would listen for).
51+
ngModel.$setViewValue(e.getContent());
52+
53+
runScopeFunction(scope, attrs.onChange, e);
54+
},
55+
onShow: function (e) {
56+
// keep the Markdown Object in $rootScope so that it's available also from anywhere (like in the parent controller)
57+
// we will keep this in an object under the ngModel name so that it also works having multiple editor in same controller
58+
$rootScope.markdownEditorObjects = $rootScope.markdownEditorObjects || {};
59+
$rootScope.markdownEditorObjects[ngModel.$name] = e;
60+
61+
if (!!attrs.onShow) {
62+
runScopeFunction(scope, attrs.onShow, e);
63+
}
3864
}
3965
});
4066
}
@@ -115,3 +141,32 @@ function addNewButtons() {
115141
}]
116142
}]];
117143
}
144+
145+
/** Evaluate a function name passed as string and run it from the scope.
146+
* The function name could be passed with/without brackets "()", in any case we will run the function
147+
* @param object self object
148+
* @param string function passed as a string
149+
* @param object Markdown Editor object
150+
* @result mixed result
151+
*/
152+
function runScopeFunction(scope, fnString, editorObject) {
153+
if (!fnString) {
154+
return;
155+
}
156+
157+
// Find if our function has the brackets "()"
158+
if (/\({1}.*\){1}/gi.test(fnString)) {
159+
// if yes then run it through $eval else find it in the scope and then run it. That is the only way to evaluate all arguments of the function
160+
// we'll have to make the object available in the scope so that we can evaluate it inside the controller
161+
var lastParenthese = fnString.indexOf(")");
162+
scope.$markdownEditorObject = editorObject;
163+
fnString = fnString.replace(")", "$markdownEditorObject)");
164+
result = scope.$eval(fnString);
165+
} else {
166+
var fct = objectFindById(scope, fnString, '.');
167+
if (typeof fct === "function") {
168+
result = fct(editorObject);
169+
}
170+
}
171+
return result;
172+
}

0 commit comments

Comments
 (0)