Events: Allow for easier application extension with hook points.
How does it work?
Every time someone wants to extend the application, instead of modifying original `publishing.js` file, he or she can subscribe to given events, e.g.
Scenario: Table Of Contents extension
```
// resources/public/js/toc.js
events.subscribe('content:rendered', function () {
// Prepend table of contents in edit mode on updates
});
events.subscribe('document:loaded', function () {
// Prepend table of contents on initial load in edit view and preview
});
```
Now, having structured way to hook into app allows to keep the main codebase maintainable and pretty stable and extremely extensible at the same time.
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
<link href="/style.css" rel="stylesheet" type="text/css" />
|
<link href="/style.css" rel="stylesheet" type="text/css" />
|
||||||
<script src="//cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.min.js" type="text/javascript"></script>
|
<script src="//cdnjs.cloudflare.com/ajax/libs/marked/0.3.5/marked.min.js" type="text/javascript"></script>
|
||||||
<script src="//cdnjs.cloudflare.com/ajax/libs/blueimp-md5/1.0.1/js/md5.min.js" type="text/javascript"></script>
|
<script src="//cdnjs.cloudflare.com/ajax/libs/blueimp-md5/1.0.1/js/md5.min.js" type="text/javascript"></script>
|
||||||
|
<script src="/js/events.js" type="text/javascript"></script>
|
||||||
<script src="/js/publishing.js" type="text/javascript"></script>
|
<script src="/js/publishing.js" type="text/javascript"></script>
|
||||||
<base target="_blank">
|
<base target="_blank">
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* Simple Event Bus
|
||||||
|
*
|
||||||
|
* Allows to easily hook into various page rendering / markdown parsing stages with custom modules
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* High Level API:
|
||||||
|
*
|
||||||
|
* // Subscribe
|
||||||
|
* events.subscribe(eventName:String, eventHandler:Function)
|
||||||
|
*
|
||||||
|
* // Publish
|
||||||
|
* events.publish(eventName:String, optionalArgument1, optionalArgument2, ..., optionalArgumentN);
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Sample Usage:
|
||||||
|
*
|
||||||
|
* event.subscribe('markdown:parsed', function () {
|
||||||
|
* console.log('Markdown Parsed');
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* event.subscribe('markdown:parsed', function (title) {
|
||||||
|
* console.log('Markdown Parsed For Document: ' + title);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* events.publish('markdown:parsed', 'SampleDocument.md');
|
||||||
|
* // Markdown Parsed
|
||||||
|
* // Markdown Parsed For Document: SampleDocument.md
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
(function (global) {
|
||||||
|
|
||||||
|
var eventBus = {
|
||||||
|
subscribers: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
global.events = global.events || {
|
||||||
|
|
||||||
|
subscribe: function (eventName, eventHandler) {
|
||||||
|
// Initialize an array of event listeners if doesn't exist already
|
||||||
|
eventBus.subscribers[eventName] = eventBus.subscribers[eventName] || [];
|
||||||
|
|
||||||
|
eventBus.subscribers[eventName].push(eventHandler);
|
||||||
|
},
|
||||||
|
|
||||||
|
publish: function (eventName /*, arg1, arg2, ..., argN */) {
|
||||||
|
var eventArguments = [].slice.call(arguments, 1);
|
||||||
|
|
||||||
|
if (eventArguments.length) {
|
||||||
|
console.log('[Hooks] "%s" with args %O', eventName, eventArguments);
|
||||||
|
} else {
|
||||||
|
console.log('[Hooks] "%s"', eventName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call event handlers with given attributes
|
||||||
|
(eventBus.subscribers[eventName] || []).forEach(function (eventHandler) {
|
||||||
|
eventHandler.apply(null, eventArguments);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
}(window));
|
||||||
@@ -25,6 +25,9 @@ function enableButton() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onLoad() {
|
function onLoad() {
|
||||||
|
// Hook point
|
||||||
|
events.publish('document:loaded');
|
||||||
|
|
||||||
$note = $("note");
|
$note = $("note");
|
||||||
$action = $("action").value;
|
$action = $("action").value;
|
||||||
$preview = $("draft");
|
$preview = $("draft");
|
||||||
@@ -37,6 +40,9 @@ function onLoad() {
|
|||||||
timer = setTimeout(function() {
|
timer = setTimeout(function() {
|
||||||
$preview.innerHTML = md2html(content);
|
$preview.innerHTML = md2html(content);
|
||||||
$tableau.innerHTML = content.split(/\s+/).length + " words";
|
$tableau.innerHTML = content.split(/\s+/).length + " words";
|
||||||
|
|
||||||
|
// Hook point
|
||||||
|
events.publish('content:rendered');
|
||||||
}, delay);
|
}, delay);
|
||||||
};
|
};
|
||||||
if ($action == "UPDATE") updatePreview();
|
if ($action == "UPDATE") updatePreview();
|
||||||
|
|||||||
@@ -12,5 +12,11 @@
|
|||||||
%CONTENT%
|
%CONTENT%
|
||||||
</article>
|
</article>
|
||||||
%FOOTER%
|
%FOOTER%
|
||||||
|
|
||||||
|
<script src="/js/events.js"></script>
|
||||||
|
<script>
|
||||||
|
events.publish('document:loaded');
|
||||||
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user