webgme
Version:
Web-based Generic Modeling Environment
291 lines (244 loc) • 9.57 kB
JavaScript
/*globals define, $*/
/*jshint browser: true*/
/**
* WebGME jquery extension
*
* @author rkereskenyi / https://github.com/rkereskenyi
*/
define(['jquery'], function () {
'use strict';
$.fn.extend({
editOnDblClick: function (params) {
this.each(function () {
$(this).on('dblclick.editOnDblClick', null, function (event) {
$(this).editInPlace(params);
event.stopPropagation();
event.preventDefault();
});
});
}
});
$.fn.extend({
editInPlace: function (params) {
var editClass = params && params.class || null,
extraCss = params && params.css || {},//Extra optional css styling
onChangeFn = params && params.onChange || null,
onFinishFn = params && params.onFinish || null,
enableEmpty = params && params.enableEmpty || false,
minHeight = 16,
fontSizeAdjust = 5;
function editInPlace(el) {
var w = el.width(),
h = el.height(),
originalValue,
inputCtrl,
keys,
i;
//check if already in edit mode
//if so, select the content
if (el.data('already-editing') === true) {
el.find('input').select().focus();
return;
}
//not editing yet, turn to edit mode now
el.data('already-editing', true);
//save old content
originalValue = el.text();
if (params && params.value) {
originalValue = params.value;
}
//create edit control
inputCtrl = $('<input/>', {
type: 'text',
value: originalValue
});
//add custom edit class
if (editClass && editClass !== '') {
inputCtrl.addClass(editClass);
}
//set css properties to fix Bootstrap's modification
h = Math.max(h, minHeight);
inputCtrl.outerWidth(w).outerHeight(h);
inputCtrl.css({
'box-sizing': 'border-box',
'margin': '0px',
'line-height': h + 'px',
'font-size': h - fontSizeAdjust
});
//add any custom css specified
keys = Object.keys(extraCss);
for (i = keys.length - 1; i >= 0; i--) {
inputCtrl.css(keys[i], extraCss[keys[i]]);
}
el.html(inputCtrl);
//set font size accordingly
//TODO: multiple line editor not handled correctly
/*h = inputCtrl.height();*/
//inputCtrl.css({'font-size': originalFontSize});
//finally put the control in focus
inputCtrl.focus();
inputCtrl.on('click', function (event) {
event.stopPropagation();
});
//hook up event handlers to 'save' and 'cancel'
inputCtrl.keydown(
function (event) {
switch (event.which) {
case 27: // [esc]
// discard changes on [esc]
inputCtrl.val(originalValue);
event.preventDefault();
event.stopPropagation();
$(this).blur();
break;
case 13: // [enter]
// simulate blur to accept new value
event.preventDefault();
event.stopPropagation();
$(this).blur();
break;
case 46:// DEL
//don't need to handle it specially but need to prevent propagation
event.stopPropagation();
break;
default:
break;
}
}
).blur(function (/*event*/) {
var newValue = inputCtrl.val();
//revert edit mode, when user leaves <input>
if (newValue === '' && enableEmpty === false) {
newValue = originalValue;
}
el.html('').text(newValue);
el.removeData('already-editing');
if (newValue !== originalValue) {
if (onChangeFn) {
onChangeFn.call(el, originalValue, newValue);
}
}
if (onFinishFn) {
onFinishFn.call(el);
}
});
}
this.each(function () {
editInPlace($(this));
});
}
});
// Canvas drawing extension
if (!!document.createElement('canvas').getContext) {
$.extend(window.CanvasRenderingContext2D.prototype, {
ellipse: function (aX, aY, r1, r2, fillIt) {
var aWidth,
aHeight,
hB,
vB,
eX,
eY,
mX,
mY;
aX = aX - r1;
aY = aY - r2;
aWidth = r1 * 2;
aHeight = r2 * 2;
hB = (aWidth / 2) * 0.5522848;
vB = (aHeight / 2) * 0.5522848;
eX = aX + aWidth;
eY = aY + aHeight;
mX = aX + aWidth / 2;
mY = aY + aHeight / 2;
this.beginPath();
this.moveTo(aX, mY);
this.bezierCurveTo(aX, mY - vB, mX - hB, aY, mX, aY);
this.bezierCurveTo(mX + hB, aY, eX, mY - vB, eX, mY);
this.bezierCurveTo(eX, mY + vB, mX + hB, eY, mX, eY);
this.bezierCurveTo(mX - hB, eY, aX, mY + vB, aX, mY);
this.closePath();
if (fillIt) {
this.fill();
}
this.stroke();
},
circle: function (aX, aY, aDiameter, fillIt) {
this.ellipse(aX, aY, aDiameter, aDiameter, fillIt);
}
});
}
/*
*
* Getting textwidth
*
*/
$.fn.extend({
textWidth: function () {
var htmlOrg,
htmlCalc,
width;
htmlOrg = $(this).html();
htmlCalc = '<span>' + htmlOrg + '</span>';
$(this).html(htmlCalc);
width = $(this).find('span:first').width();
$(this).html(htmlOrg);
return width;
}
});
$.fn.extend({
groupedAlphabetTabs: function (params) {
var defaultParams = {'groups': ['A - E', 'F - J', 'K - O', 'P - T', 'U - Z']},
opts = {},
ulBase = $('<ul class="nav nav-tabs"></ul>'),
liBase = $('<li class=""><a href="#" data-toggle="tab"></a></li>'),
hasActive = false,
ul,
li,
i,
start,
end;
$.extend(opts, defaultParams, params);
ul = ulBase.clone();
if (opts.extraTabs) {
opts.extraTabs.forEach(function (tabInfo) {
li = liBase.clone();
if (tabInfo.active === true) {
li.addClass('active');
hasActive = true;
}
li.find('a').text(tabInfo.title);
li.data('filter', tabInfo.data);
ul.append(li);
});
}
li = liBase.clone();
if (hasActive === false) {
li.addClass('active');
}
li.find('a').text('ALL');
ul.append(li);
for (i = 0; i < opts.groups.length; i += 1) {
start = opts.groups[i].split('-')[0].trim();
end = opts.groups[i].split('-')[1].trim();
li = liBase.clone();
li.find('a').text(opts.groups[i]);
li.data('filter', [start, end]);
ul.append(li);
}
this.each(function () {
$(this).append(ul.clone(true));
$(this).on('click.groupedAlphabetTabs', 'li', function (event) {
var filter = $(this).data('filter');
$(this).parent().find('li').each(function () {
$(this).removeClass('active');
});
$(this).addClass('active');
if (params && params.onClick) {
params.onClick(filter);
}
event.preventDefault();
});
});
}
});
});