Skip to content

Commit

Permalink
Initial WidgetHooks Version
Browse files Browse the repository at this point in the history
  • Loading branch information
Andreas Schönefeldt committed Nov 25, 2015
1 parent fd81f28 commit cd53e19
Show file tree
Hide file tree
Showing 12 changed files with 332 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ build/Release
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules

# Bower components
bower_components
61 changes: 61 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module.exports = function(grunt) {
// Do grunt-related things in here

'use strict';

// define the current versions here

var gruntConf = {
pkg: grunt.file.readJSON('package.json')

, bowercopy: {
options: {
srcPrefix: 'bower_components',
destPrefix: 'src'
},
all: {
files: {
'jquery.js': 'jquery/dist/jquery.min.js'
}
}
}

, watch: { // tracks changes of the watched files and rerunns the generation commands for development convenience
options: {
livereload: true,
}

, uglify : {
files: ['src/dev/*.js'],
tasks: ['uglify:prd']
}
}

, uglify: { // minify and optimize js files
options : {
screwIE8 : true
}
, prd: {
files: {
// '../static/js/global-nav-1.1.1.min.js': ['../static/js/global-nav-1.1.1.js']
}
}
}
}

gruntConf.uglify.prd.files['dist/widget-hooks.js'] = ['src/dev/widget-hooks.js'];

// Project configuration.
grunt.initConfig(gruntConf);

// load the grunt modules
grunt.loadNpmTasks('grunt-bowercopy');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-uglify');

// compilation and basic watch task.
grunt.registerTask('default', 'JS Minification', function() {
grunt.task.run('bowercopy', 'uglify', 'watch');
});

};
27 changes: 27 additions & 0 deletions bower.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "JS-Widget-Hooks",
"description": "A standardized way to initialize and handle clientside widgets",
"main": "dist/widget-hooks.js",
"authors": [
"Andreas Schönefeldt <[email protected]>"
],
"license": "MIT",
"keywords": [
"clientside",
"widgets"
],
"homepage": "https://github.com/Andreas-Schoenefeldt/js-widget-hooks",
"moduleType": [
"amd"
],
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"jquery": "~2.1.4"
}
}
1 change: 1 addition & 0 deletions dist/widget-hooks.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "JS-Widget-Hooks",
"version": "1.0.0",
"repository": "https://github.com/Andreas-Schoenefeldt/js-widget-hooks.git",
"devDependencies": {
"grunt": "^0.4.5",
"grunt-bowercopy": "^1.2.0",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-uglify": "~0.5.0",
"grunt-contrib-watch": "^0.6.1"
}
}
117 changes: 117 additions & 0 deletions src/dev/widget-hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* The Wisget Hooks, which allow to hook javascript execution in the following form:
*
* <div class="widget" id="my-widget-root" data-widgetname="my-widget">...</div>
*/
define(['jquery'], function($){

// this is the Widgets Object
return {

widgetClass : 'widget'
, scriptClass : 'dyn-script'

, vars: {} // place to put data

// registered widgets
, registered : {

}

// place for function calls after widget initialization
, registeredFinalls : {
}

// to register a new widget dynamically
// @param Number Priority - an optional priority in order to have controll, which widget is executed first
, register : function(id, func, dependencys, priority) {
var dependencysVar = (dependencys === undefined) ? false : dependencys;
if (this.registered[id]) debug("[WARNING] Widget " + id + " was already registered: Override.");
this.registered[id] = [dependencysVar, func, priority];
}

, init : function(root) {
var priorityList = []
, wdgArrays = {}
, wdg, i, k, cList, allWidgets = []
;

for (wdg in this.registered) {
priorityList[priorityList.length] = [wdg, this.registered[wdg][2]]; // 2 is the priority
wdgArrays[wdg] = [];
}

priorityList.sort(function(a, b){
if (a[1] !== undefined && b[1] == undefined) return -1;
if (a[1] == undefined && b[1] !== undefined) return 1;
return a[1] < b[1] ? 1 : (a[1] > b[1]) ? -1 : 0;
});

if (! root) root = $('body'); // fallback to complete DOM execution, if we get not a subnode

// get all the elements of the type widget
root.find('.' + this.widgetClass).each(function(){
var elem = $(this)
, names = elem.data('widgetname').split(' ')
, name
, i
;

for (i in names) {
name = names[i];
if (wdgArrays[name] !== undefined) {
wdgArrays[name].push(elem);
} else {
debug("No method for widget " + name + " provided");
}
}
});
// and initialise them according to the priority
for (i = 0; i < priorityList.length; i++) {
wdg = priorityList[i][0];
cList = wdgArrays[wdg];
if (cList.length) {
for (k = 0; k < cList.length; k++) {
allWidgets[allWidgets.length] = cList[k];
this.initSpecific(cList[k], wdg);
}

if (this.registeredFinalls[wdg]) this.registeredFinalls[wdg]();
}
delete wdgArrays[wdg]; // remove the initialized array, in order to check, if something was not initialized
}

// delete the widget class later in case of multi widgets
for (k in allWidgets) {
allWidgets[k].removeClass(this.widgetClass); // remove the class to prevent a second initialization
}
}

// @param Boolean force - allows to initialize a widget also, if it was already initialized
, initSpecific : function(elem, widgetname, force){
var that = this;

try {
if (elem.hasClass(this.widgetClass) || force){ // just in case something has changed meanwhile...

// now check, if we need external requirements
if (this.registered[widgetname][0]) {
require(this.registered[widgetname][0], function(){
that.registered[widgetname][1](elem);
elem.addClass(this.widgetClass + '-initialized');
});
} else {
this.registered[widgetname][1](elem);
elem.addClass(this.widgetClass + '-initialized');
}
}
} catch (e) {
debug("Error during execution of widget " + widgetname + ": " + e.message);
elem.addClass(this.widgetClass + '-error');
return false;
}

return true;
}
}
});
6 changes: 6 additions & 0 deletions src/jquery-private.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// http://requirejs.org/docs/jquery.html
// and the 'jquery-private' module, in the
// jquery-private.js file:
define(['jquery'], function (jQuery) {
return jQuery.noConflict(); // we do not remove everything, because we need the global jQuery variable in the window
});
5 changes: 5 additions & 0 deletions src/jquery.js

Large diffs are not rendered by default.

Loading

0 comments on commit cd53e19

Please sign in to comment.