Browse Source

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.
master
Maciej Smolinski 10 years ago
parent
commit
e25926619e
  1. 1
      resources/edit.html
  2. 62
      resources/public/js/events.js
  3. 6
      resources/public/js/publishing.js
  4. 6
      resources/template.html

1
resources/edit.html

@ -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>

62
resources/public/js/events.js

@ -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));

6
resources/public/js/publishing.js

@ -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();

6
resources/template.html

@ -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>

Loading…
Cancel
Save