Skip to content

Commit

Permalink
Add Event Hooks Callback and external fn calls
Browse files Browse the repository at this point in the history
Add Event Hooks Callback
Also make each Markdown Editor object available through
$rootScope.markdownEditorObjects[editorName]
  • Loading branch information
ghiscoding committed Nov 12, 2016
1 parent 9b7f664 commit 03fff7d
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 44 deletions.
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "angular-markdown-editor-ghiscoding",
"version": "1.0.9",
"version": "1.1.0",
"author": "Ghislain B.",
"description": "Angular Markdown Editor, all-in-one Markdown Editor and Preview",
"main": [
Expand Down
33 changes: 31 additions & 2 deletions example/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ angular.module('example-app', ['hc.marked', 'hljs', 'angular-markdown-editor'])
tabReplace: ' '
});
}])
.controller("MainController", ["$scope", "marked", function MarkdownController($scope, marked) {
$scope.markdown = "*This* **is** [markdown](https://daringfireball.net/projects/markdown/)\n and `{{ 1 + 2 }}` = {{ 1 + 2 }}";
.controller("MainController", ["$rootScope", "$scope", "marked", function MarkdownController($rootScope, $scope, marked) {
$scope.editor1 = "*This* **is** [markdown](https://daringfireball.net/projects/markdown/)\n and `{{ 1 + 2 }}` = {{ 1 + 2 }}";
$scope.markdownService = marked('#TEST');

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

/**
* For some convenience, Angular-Markdown-Editor Directive also save each Markdown Editor inside $rootScope
* Each of editor object are available through their $rootScope.markdownEditorObjects[editorName]
*
* Example: <textarea name="editor1" markdown-editor="{'iconlibrary': 'fa'}"></textarea>
* We would then call our object through $rootScope.markdownEditorObjects.editor1
*/
$scope.fullScreenPreview = function() {
$rootScope.markdownEditorObjects.editor1.showPreview();
$rootScope.markdownEditorObjects.editor1.setFullscreen(true);
}

/** Markdown event hook onFullscreen, in this example we will automatically show the result preview when going in full screen
* the argument (e) is the actual Markdown object returned which help call any of API functions defined in Markdown Editor
* For a list of API functions take a look on official demo site http://www.codingdrama.com/bootstrap-markdown/
* @param object e: Markdown Editor object
*/
$scope.onFullScreenCallback = function(e) {
e.showPreview();
}

/** After exiting from full screen, let's go back to editor mode (which mean hide the preview)
* 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
* https://github.com/toopay/bootstrap-markdown/tree/master/js
*/
$scope.onFullScreenExitCallback = function(e) {
e.hidePreview();
}

}]);
38 changes: 26 additions & 12 deletions example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@

<!-- your ng-app file -->
<script type="text/javascript" src="../src/angular-markdown-editor.js"></script>
<script type="text/javascript" src="../src/angular-markdown-editor-locale.js"></script>
<script type="text/javascript" src="app.js"></script>

<!-- You could also load any available locale -->
<script type="text/javascript" src="../node_modules/bootstrap-markdown/locale/bootstrap-markdown.fr.js"></script>
</head>

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

<hr/>

<div>
External Markdown Editor API Calls with `$rootScope.markdownEditorObjects`
<br/>
<button class="btn btn-info" ng-click="fullScreenPreview()">Full Screen Preview</button>
</div>
<hr/>
<div class="row">
<div class="col-md-12 col-lg-6">
<div class="form-group">
<label for="comment">Live Markdown with <a href="http://www.codingdrama.com/bootstrap-markdown/">Bootstrap-Markdown Editor</a>:</label>
<textarea name="content" class="content-box" markdown-editor="{'iconlibrary': 'fa', addExtraButtons: true, resize: 'vertical'}" rows="10" ng-model="markdown"></textarea>
</div>
<div class="col-md-12 col-lg-6">
<div class="form-group">
<label for="comment">Live Markdown with <a href="http://www.codingdrama.com/bootstrap-markdown/">Bootstrap-Markdown Editor</a>:</label>
<textarea name="editor1" class="content-box"
ng-model="editor1"
markdown-editor="{'iconlibrary': 'fa', addExtraButtons: true, resize: 'vertical'}"
on-fullscreen="onFullScreenCallback()"
on-fullscreen-exit="onFullScreenExitCallback()"
rows="10" >
</textarea>
</div>
<div class="col-md-12 col-lg-6 fill">
<div class="form-group">
<label for="comment">Preview Result:</label>
<div marked="markdown" class="markdown outline" style="padding: 20px">
</div>
</div>
</div>
<div class="col-md-12 col-lg-6 fill">
<div class="form-group">
<label for="comment">Preview Result:</label>
<div marked="editor1" class="markdown outline" style="padding: 20px">
</div>
</div>
</div>
</div>

<hr/>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "angular-markdown-editor",
"version": "1.0.9",
"version": "1.1.0",
"author": "Ghislain B.",
"description": "Angular Markdown Editor, all-in-one Markdown Editor and Preview",
"main": "app.js",
Expand Down
71 changes: 68 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Angular Markdown Editor (Directive)
`1.0.9`
`1.1.0`

## What do we have?
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.
Expand Down Expand Up @@ -57,8 +57,8 @@ _NOTE: Unfortunately, the "highlight.js" npm module doesn't seem to have proper
<script type="text/javascript" src="../node_modules/angular-highlightjs/src/angular-highlightjs.js"></script>
<script type="text/javascript" src="../node_modules/angular-markdown-editor/src/angular-markdown-editor.js"></script>

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

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

### Event Hooks
###### starting with Angular-Markdown-Editor version 1.1.0
You have access to all the Bootstrap Markdown Editor available events/hooks directly in the directive

_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._

- onPreview
- onPreviewEnd
- onSave
- onBlur
- onFocus
- onFullscreen
- onFullscreenExit
- onChange
- onSelect
- onShow

For example HTML
```html
<textarea name="editor1" class="content-box"
ng-model="editor1"
markdown-editor="{'iconlibrary': 'fa', addExtraButtons: true, resize: 'vertical'}"
on-fullscreen="onFullScreenCallback()"
on-fullscreen-exit="onFullScreenExitCallback()"
rows="10" >
</textarea>
```
Controller
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/)

```javascript
/** Markdown event hook onFullscreen, in this example we will automatically show the result preview when going in full screen
* the argument (e) is the actual Markdown object returned which help call any of API functions defined in Markdown Editor
* @param object e: Markdown Editor object
*/
$scope.onFullScreenCallback = function(e) {
e.showPreview();
}
```

### External function calls through $rootScope.markdownEditorObjects
###### starting with Angular-Markdown-Editor version 1.1.0
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/).
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).

For example HTML
```html
<button class="btn btn-info" ng-click="fullScreenPreview()">Full Screen Preview</button>
```

Controller
```javascript
/**
* For some convenience, Angular-Markdown-Editor Directive also save each Markdown Editor inside $rootScope
* Each of editor object are available through their $rootScope.markdownEditorObjects[editorName]
*
* Example: <textarea name="editor1" markdown-editor="{'iconlibrary': 'fa'}"></textarea>
* We would then call our object through $rootScope.markdownEditorObjects.editor1
*/
$scope.fullScreenPreview = function() {
$rootScope.markdownEditorObjects.editor1.showPreview();
$rootScope.markdownEditorObjects.editor1.setFullscreen(true);
}
```

## Preview
![Login Page](https://raw.githubusercontent.com/ghiscoding/angular-markdown-editor/master/images/scrshot_preview.png)
20 changes: 0 additions & 20 deletions src/angular-markdown-editor-locale.js

This file was deleted.

65 changes: 60 additions & 5 deletions src/angular-markdown-editor.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
angular
.module('angular-markdown-editor', [])
.directive('markdownEditor', ['$parse', function(parse) {
.directive('markdownEditor', ['$rootScope', function ($rootScope) {
return {
restrict: 'A',
require: 'ngModel',
Expand Down Expand Up @@ -31,10 +31,36 @@ angular
enableDropDataUri: options.enableDropDataUri || false,
showButtons: options.showButtons || null,
additionalButtons: options.additionalButtons || (options.addExtraButtons ? addNewButtons() : []),
onChange: function(event) {
// When a change occurs, we need to update scope in case the user clicked one of the plugin buttons
// (which isn't the same as a keydown event that angular would listen for).
ngModel.$setViewValue(event.getContent());

//-- Events/Hooks --
// each of them are defined as callback available in the directive
// example: <textarea markdown-editor="{'iconlibrary': 'fa'}" on-fullscreen-exit="vm.exitFullScreenCallback()"></textarea>
// 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
// https://github.com/toopay/bootstrap-markdown/tree/master/js
onPreview: function (e) { runScopeFunction(scope, attrs.onPreview, e); },
onPreviewEnd: function (e) { runScopeFunction(scope, attrs.onPreviewEnd, e); },
onSave: function (e) { runScopeFunction(scope, attrs.onSave, e); },
onBlur: function (e) { runScopeFunction(scope, attrs.onBlur, e); },
onFocus: function (e) { runScopeFunction(scope, attrs.onFocus, e); },
onFullscreen: function (e) { runScopeFunction(scope, attrs.onFullscreen, e); },
onSelect: function (e) { runScopeFunction(scope, attrs.onSelect, e); },
onFullscreenExit: function (e) { runScopeFunction(scope, attrs.onFullscreenExit, e); },
onChange: function(e) {
// When a change occurs, we need to update scope in case the user clicked one of the plugin buttons
// (which isn't the same as a keydown event that angular would listen for).
ngModel.$setViewValue(e.getContent());

runScopeFunction(scope, attrs.onChange, e);
},
onShow: function (e) {
// keep the Markdown Object in $rootScope so that it's available also from anywhere (like in the parent controller)
// we will keep this in an object under the ngModel name so that it also works having multiple editor in same controller
$rootScope.markdownEditorObjects = $rootScope.markdownEditorObjects || {};
$rootScope.markdownEditorObjects[ngModel.$name] = e;

if (!!attrs.onShow) {
runScopeFunction(scope, attrs.onShow, e);
}
}
});
}
Expand Down Expand Up @@ -115,3 +141,32 @@ function addNewButtons() {
}]
}]];
}

/** Evaluate a function name passed as string and run it from the scope.
* The function name could be passed with/without brackets "()", in any case we will run the function
* @param object self object
* @param string function passed as a string
* @param object Markdown Editor object
* @result mixed result
*/
function runScopeFunction(scope, fnString, editorObject) {
if (!fnString) {
return;
}

// Find if our function has the brackets "()"
if (/\({1}.*\){1}/gi.test(fnString)) {
// 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
// we'll have to make the object available in the scope so that we can evaluate it inside the controller
var lastParenthese = fnString.indexOf(")");
scope.$markdownEditorObject = editorObject;
fnString = fnString.replace(")", "$markdownEditorObject)");
result = scope.$eval(fnString);
} else {
var fct = objectFindById(scope, fnString, '.');
if (typeof fct === "function") {
result = fct(editorObject);
}
}
return result;
}

0 comments on commit 03fff7d

Please sign in to comment.