Merge branch 'release-1.4.0'

This commit is contained in:
vitalets 2013-01-11 21:12:12 +04:00
commit e1b3dbfc53
81 changed files with 12913 additions and 1273 deletions
CHANGELOG.txtREADME.mdgrunt.jspackage.json
src
test

@ -2,6 +2,32 @@ X-editable changelog
=============================
Version 1.4.0 Jan 11, 2013
----------------------------
[enh] added new input type: combodate (vitalets)
[bug #68] allow arrays for data attributes (adimitrov)
[enh] setValue method updates input if form is open (vitalets)
[enh] select: change source via option method, see #61 (vitalets)
[bug] select: source loaded twice if sourceCache = false (vitalets)
[enh] added `destroy` method, see #61 (vitalets)
[enh] textarea: added `rows` property (vitalets)
[enh #60] added wysihtml5 input (vitalets)
[enh] added IOS-style clear button for text inputs (vitalets)
[enh] date inputs changed in inline mode (vitalets)
[enh #51] popup/inline modes can be toggled via `mode` config option. No more *-inline.js versions of files (vitalets)
[enh] update bootstrap-datepicker to upstream (vitalets)
[enh] 'display' method: added param 'response' allowing to show text directly from server (vitalets)
[enh] new util method `$.fn.editableutils.itemsByValue` to easily get selected items for sourced-inputs (vitalets)
[enh] convert newlines to <br> in error message for more pretty display (vitalets)
[enh #57] remove css height for textarea (vitalets)
[enh] if new value for select is 'null' source should not load (vitalets)
[enh #53] 'name' no more appended to source defined as url (vitalets)
[enh #46] move 'img' dir outside 'css' (vitalets)
[enh #48] fix handling of newlines in textarea input (jmfontaine)
[enh #47] set select source to function (brianchance)
[bug] fix inline container move on next line in IE7 (vitalets)
Version 1.3.0 Dec 10, 2012
----------------------------
[enh] added html5 inputs support: password, email, url, tel, number, range (vitalets)
@ -54,8 +80,8 @@ Version 1.1.1 Nov 30, 2012
[enh #13] 'onblur' option: to cancel, submit or ignore when user clicks outside the form (vitalets)
[enh] 'ajaxOptions' parameter for advanced ajax configuration (vitalets)
[enh] 'success' callback can return object to overwrite submitted value (vitalets)
Version 1.1.0 Nov 27, 2012
----------------------------
[enh #11] icon cancel changed to 'cross' (tarciozemel)
@ -65,7 +91,7 @@ Version 1.1.0 Nov 27, 2012
[enh] form template changed: added DIV.editable-input, DIV.editable.buttons and $.fn.editableform.buttons (vitalets)
[enh] new input type: checklist (vitalets)
[enh] updated docs: inputs dropdown menu, global templates section (vitalets)
Version 1.0.1 Nov 22, 2012
----------------------------
@ -74,8 +100,8 @@ Version 1.0.1 Nov 22, 2012
[enh #1] params can be a function to calculate it dynamically (vitalets)
[enh #6] do not preventDefault() in click when toggle='manual'. This allows to have clickable links (vitalets)
[bug #3] should not mark element with unsave css if url is user's function (vitalets)
Version 1.0.0 Nov 19, 2012
----------------------------
Initial release. This library is new life of bootstrap-editable (1.1.4) that was strongly refactored and improved.
@ -84,7 +110,7 @@ Main features:
- different container classes to show form: popover, tooltip, poshytip, etc
- inline and popup versions
- new directory structure and logic in separate js files allowing easy contribution
It is not fully compatible with bootstrap-editable but has mainly the same interface and api.
Here list of differences to help you to upgrade your application:

@ -8,9 +8,9 @@ See **http://vitalets.github.com/x-editable**
## Reporting issues
When creating issues please provide [jsFiddle](http://jsfiddle.net) example. You can easily fork one of **jsFiddle templates**:
1. [bootstrap](http://jsfiddle.net/xBB5x/25/)
2. [jqueryui](http://jsfiddle.net/xBB5x/24/)
3. [plain](http://jsfiddle.net/xBB5x/23/)
1. [bootstrap](http://jsfiddle.net/xBB5x/195)
2. [jqueryui](http://jsfiddle.net/xBB5x/196)
3. [plain](http://jsfiddle.net/xBB5x/197)
Your feedback is very appreciated!
## Contribution

@ -11,31 +11,39 @@ function getFiles() {
bootstrap: {
form: [forms+'editable-form-bootstrap.js'],
container: [containers+'editable-popover.js'],
inputs: [inputs+'date/date.js', inputs+'date/bootstrap-datepicker/js/bootstrap-datepicker.js'],
inputs: [
inputs+'date/date.js',
inputs+'date/datefield.js',
inputs+'date/bootstrap-datepicker/js/bootstrap-datepicker.js'],
css: [inputs+'date/bootstrap-datepicker/css/datepicker.css']
},
jqueryui: {
form: [forms+'editable-form-jqueryui.js'],
container: [containers+'editable-tooltip.js'],
inputs: [inputs+'dateui/dateui.js'],
inputs: [
inputs+'dateui/dateui.js',
inputs+'dateui/dateuifield.js'
],
css: []
},
jquery: {
form: [],
container: [containers+'editable-poshytip.js'],
inputs: [inputs+'dateui/dateui.js'],
inputs: [
inputs+'dateui/dateui.js',
inputs+'dateui/dateuifield.js'
],
css: []
}
};
var inline = [containers+'editable-inline.js'];
//common js files
var js = [
'<banner:meta.banner>',
forms+'editable-form.js',
forms+'editable-form-utils.js',
containers+'editable-container.js',
containers+'editable-inline.js',
lib+'element/editable-element.js',
inputs+'abstract.js',
inputs+'list.js',
@ -43,7 +51,9 @@ function getFiles() {
inputs+'textarea.js',
inputs+'select.js',
inputs+'checklist.js',
inputs+'html5types.js'
inputs+'html5types.js',
inputs+'combodate/lib/combodate.js',
inputs+'combodate/combodate.js'
];
//common css files
@ -59,8 +69,8 @@ function getFiles() {
for(var k in config) {
folder = '<%= dist %>/'+k+'-editable/';
//popup
task = k+'_popup_js';
//js
task = k+'_js';
dest = folder+'js/'+k+'-editable'+ (k === 'jquery' ? '-poshytip' : '');
concat_files[task] = {
src: js.concat(config[k].form).concat(config[k].container).concat(config[k].inputs),
@ -71,18 +81,6 @@ function getFiles() {
dest: dest + '.min.js'
};
//inline
task = k+'_inline_js';
dest = folder+'js/'+k+'-editable-inline';
concat_files[task] = {
src: js.concat(config[k].form).concat(inline).concat(config[k].inputs),
dest: dest+'.js'
};
min_files[task] = {
src: ['<banner:meta.banner>', '<config:concat.'+task+'.dest>'],
dest: dest + '.min.js'
};
//css
concat_files[k+'_css'] = {
src: css.concat(config[k].css),
@ -158,12 +156,15 @@ module.exports = function(grunt) {
files: ['grunt.js',
'src/editable-form/*.js',
'src/containers/*.js',
'src/inputs/*.js',
'src/element/*.js',
'src/inputs/*.js',
'src/inputs/date/date.js',
'src/inputs/dateui/dateui.js',
'src/inputs-ext/**/*.js'
'src/inputs/date/*.js',
'src/inputs/dateui/*.js',
'src/inputs/combodate/*.js',
'src/inputs-ext/address/*.js',
'src/inputs-ext/wysihtml5/*.js'
]
},
/*
@ -194,9 +195,9 @@ module.exports = function(grunt) {
copy: {
dist: {
files: {
'<%= dist %>/bootstrap-editable/css/img/' : 'src/editable-form/img/*',
'<%= dist %>/jqueryui-editable/css/img/' : 'src/editable-form/img/*',
'<%= dist %>/jquery-editable/css/img/' : 'src/editable-form/img/*',
'<%= dist %>/bootstrap-editable/img/' : 'src/img/*',
'<%= dist %>/jqueryui-editable/img/' : 'src/img/*',
'<%= dist %>/jquery-editable/img/' : 'src/img/*',
//licences
'<%= dist %>/': ['LICENSE-MIT', 'README.md', 'CHANGELOG.txt']
},
@ -213,11 +214,11 @@ module.exports = function(grunt) {
}
},
ui_datepicker: {
files: {
files: {
//copy jquery ui datepicker
'<%= dist %>/jquery-editable/jquery-ui-datepicker/' : 'src/inputs/dateui/jquery-ui-datepicker/**'
'<%= dist %>/jquery-editable/jquery-ui-datepicker/' : 'src/inputs/dateui/jquery-ui-datepicker/**'
}
}
}
},
uglify: {}

@ -2,7 +2,7 @@
"name": "X-editable",
"title": "X-editable",
"description": "In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery",
"version": "1.3.0",
"version": "1.4.0",
"homepage": "http://github.com/vitalets/x-editable",
"author": {
"name": "Vitaliy Potapov",

@ -8,9 +8,12 @@
}
.editable-container.editable-inline {
/* display: inline; */ /* display: inline does not correctly work with show()/hide() in jquery <= 1.7.2 */
display: inline-block;
vertical-align: middle;
width: auto;
/* inline-block emulation for IE7*/
zoom: 1;
*display: inline;
}
.editable-container.ui-widget {

@ -9,12 +9,16 @@ Applied as jQuery method.
**/
(function ($) {
var EditableContainer = function (element, options) {
var Popup = function (element, options) {
this.init(element, options);
};
var Inline = function (element, options) {
this.init(element, options);
};
//methods
EditableContainer.prototype = {
Popup.prototype = {
containerName: null, //tbd in child class
innerCss: null, //tbd in child class
init: function(element, options) {
@ -22,6 +26,10 @@ Applied as jQuery method.
//todo: what is in priority: data or js?
this.options = $.extend({}, $.fn.editableContainer.defaults, $.fn.editableutils.getConfigData(this.$element), options);
this.splitOptions();
//set scope of form callbacks to element
this.formOptions.scope = this.$element[0];
this.initContainer();
//bind 'destroyed' listener to destroy container when element is removed from dom
@ -29,7 +37,7 @@ Applied as jQuery method.
this.destroy();
}, this));
//attach document handlers (once)
//attach document handler to close containers on click / escape
if(!$(document).data('editable-handlers-attached')) {
//close all on escape
$(document).on('keyup.editable', function (e) {
@ -41,15 +49,22 @@ Applied as jQuery method.
//close containers when click outside
$(document).on('click.editable', function(e) {
var $target = $(e.target);
var $target = $(e.target), i,
exclude_classes = ['.editable-container',
'.ui-datepicker-header',
'.modal-backdrop',
'.bootstrap-wysihtml5-insert-image-modal',
'.bootstrap-wysihtml5-insert-link-modal'];
//if click inside some editableContainer --> no nothing
if($target.is('.editable-container') || $target.parents('.editable-container').length || $target.parents('.ui-datepicker-header').length) {
return;
} else {
//close all open containers (except one)
EditableContainer.prototype.closeOthers(e.target);
//if click inside one of exclude classes --> no nothing
for(i=0; i<exclude_classes.length; i++) {
if($target.is(exclude_classes[i]) || $target.parents(exclude_classes[i]).length) {
return;
}
}
//close all open containers (except one - target)
Popup.prototype.closeOthers(e.target);
});
$(document).data('editable-handlers-attached', true);
@ -61,6 +76,7 @@ Applied as jQuery method.
this.containerOptions = {};
this.formOptions = {};
var cDef = $.fn[this.containerName].defaults;
//keys defined in container defaults go to container, others go to form
for(var k in this.options) {
if(k in cDef) {
this.containerOptions[k] = this.options[k];
@ -70,18 +86,34 @@ Applied as jQuery method.
}
},
/*
Returns jquery object of container
@method tip()
*/
tip: function() {
return this.container() ? this.container().$tip : null;
},
/* returns container object */
container: function() {
return this.$element.data(this.containerName);
},
call: function() {
this.$element[this.containerName].apply(this.$element, arguments);
},
initContainer: function(){
this.call(this.containerOptions);
},
initForm: function() {
this.formOptions.scope = this.$element[0]; //set scope of form callbacks to element
this.$form = $('<div>')
renderForm: function() {
this.$form
.editableform(this.formOptions)
.on({
save: $.proxy(this.save, this),
cancel: $.proxy(function(){ this.hide('cancel'); }, this),
nochange: $.proxy(function(){ this.hide('nochange'); }, this),
save: $.proxy(this.save, this), //click on submit button (value changed)
nochange: $.proxy(function(){ this.hide('nochange'); }, this), //click on submit button (value NOT changed)
cancel: $.proxy(function(){ this.hide('cancel'); }, this), //click on calcel button
show: $.proxy(this.setPosition, this), //re-position container every time form is shown (occurs each time after loading state)
rendering: $.proxy(this.setPosition, this), //this allows to place container correctly when loading shown
rendered: $.proxy(function(){
@ -98,31 +130,16 @@ Applied as jQuery method.
**/
this.$element.triggerHandler('shown');
}, this)
});
return this.$form;
})
.editableform('render');
},
/*
Returns jquery object of container
@method tip()
*/
tip: function() {
return this.container().$tip;
},
container: function() {
return this.$element.data(this.containerName);
},
call: function() {
this.$element[this.containerName].apply(this.$element, arguments);
},
/**
Shows container with form
@method show()
@param {boolean} closeAll Whether to close all other editable containers when showing this one. Default true.
**/
**/
/* Note: poshytip owerwrites this method totally! */
show: function (closeAll) {
this.$element.addClass('editable-open');
if(closeAll !== false) {
@ -130,16 +147,37 @@ Applied as jQuery method.
this.closeOthers(this.$element[0]);
}
//show container itself
this.innerShow();
},
/* internal show method. To be overwritten in child classes */
innerShow: function () {
this.call('show');
this.tip().addClass('editable-container');
this.initForm();
this.tip().find(this.innerCss).empty().append(this.$form);
this.$form.editableform('render');
/*
Currently, form is re-rendered on every show.
The main reason is that we dont know, what container will do with content when closed:
remove(), detach() or just hide().
Detaching form itself before hide and re-insert before show is good solution,
but visually it looks ugly, as container changes size before hide.
*/
//if form already exist - delete previous data
if(this.$form) {
//todo: destroy prev data!
//this.$form.destroy();
}
this.$form = $('<div>');
//insert form into container body
if(this.tip().is(this.innerCss)) {
//for inline container
this.tip().append(this.$form);
} else {
this.tip().find(this.innerCss).append(this.$form);
}
//render form
this.renderForm();
},
/**
@ -151,8 +189,10 @@ Applied as jQuery method.
if(!this.tip() || !this.tip().is(':visible') || !this.$element.hasClass('editable-open')) {
return;
}
this.$element.removeClass('editable-open');
this.innerHide();
/**
Fired when container was hidden. It occurs on both save or cancel.
@ -170,9 +210,14 @@ Applied as jQuery method.
this.$element.triggerHandler('hidden', reason);
},
/* internal show method. To be overwritten in child classes */
innerShow: function () {
},
/* internal hide method. To be overwritten in child classes */
innerHide: function () {
this.call('hide');
},
/**
@ -181,7 +226,7 @@ Applied as jQuery method.
@param {boolean} closeAll Whether to close all other editable containers when showing this one. Default true.
**/
toggle: function(closeAll) {
if(this.tip && this.tip().is(':visible')) {
if(this.container() && this.tip() && this.tip().is(':visible')) {
this.hide();
} else {
this.show(closeAll);
@ -249,9 +294,17 @@ Applied as jQuery method.
@method destroy()
**/
destroy: function() {
this.call('destroy');
this.hide();
this.innerDestroy();
this.$element.off('destroyed');
this.$element.removeData('editableContainer');
},
/* to be overwritten in child classes */
innerDestroy: function() {
},
/*
Closes other containers except one related to passed element.
Other containers can be cancelled or submitted (depends on onblur option)
@ -310,11 +363,12 @@ Applied as jQuery method.
return this.each(function () {
var $this = $(this),
dataKey = 'editableContainer',
data = $this.data(dataKey),
options = typeof option === 'object' && option;
data = $this.data(dataKey),
options = typeof option === 'object' && option,
Constructor = (options.mode === 'inline') ? Inline : Popup;
if (!data) {
$this.data(dataKey, (data = new EditableContainer(this, options)));
$this.data(dataKey, (data = new Constructor(this, options)));
}
if (typeof option === 'string') { //call method
@ -323,8 +377,9 @@ Applied as jQuery method.
});
};
//store constructor
$.fn.editableContainer.Constructor = EditableContainer;
//store constructors
$.fn.editableContainer.Popup = Popup;
$.fn.editableContainer.Inline = Inline;
//defaults
$.fn.editableContainer.defaults = {
@ -363,7 +418,25 @@ Applied as jQuery method.
@default 'cancel'
@since 1.1.1
**/
onblur: 'cancel'
onblur: 'cancel',
/**
Animation speed (inline mode)
@property anim
@type string
@default 'fast'
**/
anim: 'fast',
/**
Mode of editable, can be `popup` or `inline`
@property mode
@type string
@default 'popup'
@since 1.4.0
**/
mode: 'popup'
};
/*

@ -3,58 +3,48 @@
* ---------------------
*/
(function ($) {
//copy prototype from EditableContainer
//extend methods
$.extend($.fn.editableContainer.Constructor.prototype, {
$.extend($.fn.editableContainer.Inline.prototype, $.fn.editableContainer.Popup.prototype, {
containerName: 'editableform',
innerCss: null,
innerCss: '.editable-inline',
initContainer: function(){
//no init for container
//only convert anim to miliseconds (int)
//container is <span> element
this.$tip = $('<span></span>').addClass('editable-inline');
//convert anim to miliseconds (int)
if(!this.options.anim) {
this.options.anim = 0;
}
},
splitOptions: function() {
//all options are passed to form
this.containerOptions = {};
this.formOptions = this.options;
},
tip: function() {
return this.$form;
return this.$tip;
},
innerShow: function () {
this.$element.hide();
if(this.$form) {
this.$form.remove();
}
this.initForm();
this.tip().addClass('editable-container').addClass('editable-inline');
this.$form.insertAfter(this.$element);
this.$form.show(this.options.anim);
this.$form.editableform('render');
this.tip().insertAfter(this.$element).show();
},
innerHide: function () {
this.$form.hide(this.options.anim, $.proxy(function() {
this.$tip.hide(this.options.anim, $.proxy(function() {
this.$element.show();
this.tip().empty().remove();
}, this));
},
destroy: function() {
innerDestroy: function() {
this.tip().remove();
}
});
//defaults
$.fn.editableContainer.defaults = $.extend({}, $.fn.editableContainer.defaults, {
anim: 'fast'
});
}(window.jQuery));

@ -6,7 +6,7 @@
(function ($) {
//extend methods
$.extend($.fn.editableContainer.Constructor.prototype, {
$.extend($.fn.editableContainer.Popup.prototype, {
containerName: 'popover',
//for compatibility with bootstrap <= 2.2.1 (content inserted into <p> instead of directly .popover-content)
innerCss: $($.fn.popover.defaults.template).find('p').length ? '.popover-content p' : '.popover-content',
@ -15,10 +15,39 @@
$.extend(this.containerOptions, {
trigger: 'manual',
selector: false,
content: ' '
content: ' ',
template: $.fn.popover.defaults.template
});
//as template property is used in inputs, hide it from popover
var t;
if(this.$element.data('template')) {
t = this.$element.data('template');
this.$element.removeData('template');
}
this.call(this.containerOptions);
},
if(t) {
//restore data('template')
this.$element.data('template', t);
}
},
/* show */
innerShow: function () {
this.call('show');
},
/* hide */
innerHide: function () {
this.call('hide');
},
/* destroy */
innerDestroy: function() {
this.call('destroy');
},
setContainerOption: function(key, value) {
this.container().options[key] = value;
@ -82,11 +111,4 @@
}
});
//defaults
/*
$.fn.editableContainer.defaults = $.extend({}, $.fn.popover.defaults, $.fn.editableContainer.defaults, {
});
*/
}(window.jQuery));

@ -6,7 +6,7 @@
(function ($) {
//extend methods
$.extend($.fn.editableContainer.Constructor.prototype, {
$.extend($.fn.editableContainer.Popup.prototype, {
containerName: 'poshytip',
innerCss: 'div.tip-inner',
@ -20,20 +20,41 @@
});
this.call(this.containerOptions);
var $content = $('<div>')
.append($('<label>').text(this.options.title || this.$element.data( "title") || this.$element.data( "originalTitle")))
.append(this.initForm());
this.call('update', $content);
},
innerShow: function () {
this.$form.editableform('render');
/*
Overwrite totally show() method as poshytip requires content is set before show
*/
show: function (closeAll) {
this.$element.addClass('editable-open');
if(closeAll !== false) {
//close all open containers (except this)
this.closeOthers(this.$element[0]);
}
//render form
this.$form = $('<div>');
this.renderForm();
var $label = $('<label>').text(this.options.title || this.$element.data( "title") || this.$element.data( "originalTitle")),
$content = $('<div>').append($label).append(this.$form);
this.call('update', $content);
this.call('show');
this.tip().addClass('editable-container');
this.$form.data('editableform').input.activate();
},
},
/* hide */
innerHide: function () {
this.call('hide');
},
/* destroy */
innerDestroy: function() {
this.call('destroy');
},
setPosition: function() {
this.container().refresh(false);

@ -6,7 +6,7 @@
(function ($) {
//extend methods
$.extend($.fn.editableContainer.Constructor.prototype, {
$.extend($.fn.editableContainer.Popup.prototype, {
containerName: 'tooltip',
innerCss: '.ui-tooltip-content',
@ -47,25 +47,23 @@
},
tip: function() {
return this.container()._find(this.container().element);
return this.container() ? this.container()._find(this.container().element) : null;
},
innerShow: function() {
this.call('open');
this.tip().addClass('editable-container');
this.initForm();
this.tip().find(this.innerCss)
.empty()
.append($('<label>').text(this.options.title || this.$element.data( "ui-tooltip-title") || this.$element.data( "originalTitle")))
.append(this.$form);
this.$form.editableform('render');
var label = this.options.title || this.$element.data( "ui-tooltip-title") || this.$element.data( "originalTitle");
this.tip().find(this.innerCss).empty().append($('<label>').text(label));
},
innerHide: function() {
this.call('close');
},
innerDestroy: function() {
/* tooltip destroys itself on hide */
},
setPosition: function() {
this.tip().position( $.extend({
of: this.$element
@ -102,19 +100,8 @@
}
this.containerOptions.position = pos;
},
destroy: function() {
//jqueryui tooltip destroys itself
}
}
});
//defaults
/*
$.fn.editableContainer.defaults = $.extend({}, $.fn.tooltip.defaults, $.fn.editableContainer.defaults, {
items: '*',
content: ' ',
});
*/
}(window.jQuery));

@ -88,19 +88,22 @@
return newObj;
},
/**
* exclude complex objects from $.data() before pass to config
/*
exclude complex objects from $.data() before pass to config
*/
getConfigData: function($element) {
var data = {};
$.each($element.data(), function(k, v) {
if(typeof v !== 'object' || (v && typeof v === 'object' && v.constructor === Object)) {
if(typeof v !== 'object' || (v && typeof v === 'object' && (v.constructor === Object || v.constructor === Array))) {
data[k] = v;
}
});
return data;
},
/*
returns keys of object
*/
objectKeys: function(o) {
if (Object.keys) {
return Object.keys(o);
@ -124,6 +127,78 @@
**/
escape: function(str) {
return $('<div>').text(str).html();
}
},
/*
returns array items from sourceData having value property equal or inArray of 'value'
*/
itemsByValue: function(value, sourceData) {
if(!sourceData || value === null) {
return [];
}
//convert to array
if(!$.isArray(value)) {
value = [value];
}
/*jslint eqeq: true*/
var result = $.grep(sourceData, function(o){
return $.grep(value, function(v){ return v == o.value; }).length;
});
/*jslint eqeq: false*/
return result;
},
/*
Returns input by options: type, mode.
*/
createInput: function(options) {
var TypeConstructor, typeOptions, input,
type = options.type;
//`date` is some kind of virtual type that is transformed to one of exact types
//depending on mode and core lib
if(type === 'date') {
//inline
if(options.mode === 'inline') {
if($.fn.editabletypes.datefield) {
type = 'datefield';
} else if($.fn.editabletypes.dateuifield) {
type = 'dateuifield';
}
//popup
} else {
if($.fn.editabletypes.date) {
type = 'date';
} else if($.fn.editabletypes.dateui) {
type = 'dateui';
}
}
//if type still `date` and not exist in types, replace with `combodate` that is base input
if(type === 'date' && !$.fn.editabletypes.date) {
type = 'combodate';
}
}
//change wysihtml5 to textarea for jquery UI and plain versions
if(type === 'wysihtml5' && !$.fn.editabletypes[type]) {
type = 'textarea';
}
//create input of specified type. Input will be used for converting value, not in form
if(typeof $.fn.editabletypes[type] === 'function') {
TypeConstructor = $.fn.editabletypes[type];
typeOptions = this.sliceObj(options, this.objectKeys(TypeConstructor.defaults));
input = new TypeConstructor(typeOptions);
return input;
} else {
$.error('Unknown type: '+ type);
return false;
}
}
};
}(window.jQuery));
}(window.jQuery));

@ -11,7 +11,7 @@
display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
vertical-align: top;
margin-left: 7px;
/* display-inline emulation for IE7*/
/* inline-block emulation for IE7*/
zoom: 1;
*display: inline;
}
@ -39,7 +39,7 @@
}
.editableform-loading {
background: url('img/loading.gif') center center no-repeat;
background: url('../img/loading.gif') center center no-repeat;
height: 25px;
width: auto;
min-width: 25px;
@ -65,10 +65,6 @@
color: red;
}
.editableform textarea {
height: 150px; /*default height for textarea*/
}
.editableform .editable-date {
padding: 0;
margin: 0;
@ -87,9 +83,45 @@
white-space: nowrap;
}
/* set exact width of textarea to fit buttons toolbar */
.editable-wysihtml5 {
width: 566px;
height: 250px;
}
/* clear button shown as link in date inputs */
.editable-clear {
clear: both;
font-size: 0.9em;
text-decoration: none;
text-align: right;
}
}
/* IOS-style clear button for text inputs */
.editable-clear-x {
background: url('../img/clear.png') center center no-repeat;
display: block;
width: 13px;
height: 13px;
position: absolute;
opacity: 0.6;
z-index: 100;
}
.editable-clear-x:hover {
opacity: 1;
}
/*
.editable-clear-x1 {
background: url('../img/clear.png') center center no-repeat;
display: inline-block;
zoom: 1;
*display: inline;
width: 13px;
height: 13px;
vertical-align: middle;
position: relative;
margin-left: -20px;
}
*/

@ -15,24 +15,16 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
if(!this.options.scope) {
this.options.scope = this;
}
this.initInput();
//nothing shown after init
};
EditableForm.prototype = {
constructor: EditableForm,
initInput: function() { //called once
var TypeConstructor, typeOptions;
//create input of specified type
if(typeof $.fn.editabletypes[this.options.type] === 'function') {
TypeConstructor = $.fn.editabletypes[this.options.type];
typeOptions = $.fn.editableutils.sliceObj(this.options, $.fn.editableutils.objectKeys(TypeConstructor.defaults));
this.input = new TypeConstructor(typeOptions);
} else {
$.error('Unknown type: '+ this.options.type);
return;
}
//take input from options (as it is created in editable-element)
this.input = this.options.input;
//set initial value
this.value = this.input.str2value(this.options.value);
},
initTemplate: function() {
@ -47,47 +39,49 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
@method render
**/
render: function() {
//init loader
this.$loading = $($.fn.editableform.loading);
this.$div.empty().append(this.$loading);
this.showLoading();
//init form template and buttons
this.initTemplate();
this.initTemplate();
if(this.options.showbuttons) {
this.initButtons();
} else {
this.$form.find('.editable-buttons').remove();
}
//show loading state
this.showLoading();
/**
Fired when rendering starts
@event rendering
@param {Object} event event object
**/
this.$div.triggerHandler('rendering');
//init input
this.initInput();
//append input to form
this.input.prerender();
this.$form.find('div.editable-input').append(this.input.$tpl);
//append form to container
this.$div.append(this.$form);
//render input
$.when(this.input.render())
.then($.proxy(function () {
//input
this.$form.find('div.editable-input').append(this.input.$input);
//automatically submit inputs when no buttons shown
//setup input to submit automatically when no buttons shown
if(!this.options.showbuttons) {
this.input.autosubmit();
}
//"clear" link
if(this.input.$clear) {
this.$form.find('div.editable-input').append($('<div class="editable-clear">').append(this.input.$clear));
}
//append form to container
this.$div.append(this.$form);
//attach 'cancel' handler
this.$form.find('.editable-cancel').click($.proxy(this.cancel, this));
if(this.input.error) {
this.error(this.input.error);
this.$form.find('.editable-submit').attr('disabled', true);
@ -111,6 +105,11 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
this.$div.triggerHandler('rendered');
this.showForm();
//call postrender method to perform actions required visibility of form
if(this.input.postrender) {
this.input.postrender();
}
}, this));
},
cancel: function() {
@ -122,11 +121,17 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
this.$div.triggerHandler('cancel');
},
showLoading: function() {
var w;
var w, h;
if(this.$form) {
//set loading size equal to form
this.$loading.width(this.$form.outerWidth());
this.$loading.height(this.$form.outerHeight());
//set loading size equal to form
w = this.$form.outerWidth();
h = this.$form.outerHeight();
if(w) {
this.$loading.width(w);
}
if(h) {
this.$loading.height(h);
}
this.$form.hide();
} else {
//stretch loading to fill container width
@ -154,14 +159,23 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
error: function(msg) {
var $group = this.$form.find('.control-group'),
$block = this.$form.find('.editable-error-block');
$block = this.$form.find('.editable-error-block'),
lines;
if(msg === false) {
$group.removeClass($.fn.editableform.errorGroupClass);
$block.removeClass($.fn.editableform.errorBlockClass).empty().hide();
} else {
//convert newline to <br> for more pretty error display
if(msg) {
lines = msg.split("\n");
for (var i = 0; i < lines.length; i++) {
lines[i] = $('<div>').text(lines[i]).html();
}
msg = lines.join('<br>');
}
$group.addClass($.fn.editableform.errorGroupClass);
$block.addClass($.fn.editableform.errorBlockClass).text(msg).show();
$block.addClass($.fn.editableform.errorBlockClass).html(msg).show();
}
},
@ -294,10 +308,15 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
},
option: function(key, value) {
this.options[key] = value;
if(key in this.options) {
this.options[key] = value;
}
if(key === 'value') {
this.setValue(value);
}
//do not pass option to input as it is passed in editable-element
},
setValue: function(value, convertStr) {
@ -306,6 +325,11 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
} else {
this.value = value;
}
//if form is visible, update input
if(this.$form && this.$form.is(':visible')) {
this.input.value2input(this.value);
}
}
};
@ -367,7 +391,7 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
url: function(params) {
if(params.value === 'abc') {
var d = new $.Deferred;
return d.reject('field cannot be "abc"'); //returning error via deferred object
return d.reject('error message'); //returning error via deferred object
} else {
someModel.set(params.name, params.value); //save data in some js model
}
@ -458,21 +482,21 @@ Editableform is linked with one of input types, e.g. 'text', 'select' etc.
/**
Additional options for ajax request.
List of values: http://api.jquery.com/jQuery.ajax
@property ajaxOptions
@type object
@default null
@since 1.1.1
@example
ajaxOptions: {
type: 'put',
dataType: 'json'
}
**/
ajaxOptions: null,
/**
Whether to show buttons or not.
Form without buttons can be auto-submitted by input or by onblur = 'submit'.
@example
ajaxOptions: {
method: 'PUT',
dataType: 'xml'
}
Form without buttons is auto-submitted.
@property showbuttons
@type boolean

@ -15,27 +15,15 @@ Makes editable any HTML element on the page. Applied as jQuery method.
Editable.prototype = {
constructor: Editable,
init: function () {
var TypeConstructor,
isValueByText = false,
doAutotext,
finalize;
var isValueByText = false,
doAutotext, finalize;
//editableContainer must be defined
if(!$.fn.editableContainer) {
$.error('You must define $.fn.editableContainer via including corresponding file (e.g. editable-popover.js)');
return;
}
//name
this.options.name = this.options.name || this.$element.attr('id');
//create input of specified type. Input will be used for converting value, not in form
if(typeof $.fn.editabletypes[this.options.type] === 'function') {
TypeConstructor = $.fn.editabletypes[this.options.type];
this.typeOptions = $.fn.editableutils.sliceObj(this.options, $.fn.editableutils.objectKeys(TypeConstructor.defaults));
this.input = new TypeConstructor(this.typeOptions);
} else {
$.error('Unknown type: '+ this.options.type);
this.input = $.fn.editableutils.createInput(this.options);
if(!this.input) {
return;
}
@ -96,8 +84,12 @@ Makes editable any HTML element on the page. Applied as jQuery method.
@event init
@param {Object} event event object
@param {Object} editable editable instance
@param {Object} editable editable instance (as here it cannot accessed via data('editable'))
@since 1.2.0
@example
$('#username').on('init', function(e, editable) {
alert('initialized ' + editable.options.name);
});
**/
this.$element.triggerHandler('init', this);
}, this));
@ -108,18 +100,20 @@ Makes editable any HTML element on the page. Applied as jQuery method.
Can call custom display method from options.
Can return deferred object.
@method render()
@param {mixed} response server response (if exist) to pass into display function
*/
render: function() {
render: function(response) {
//do not display anything
if(this.options.display === false) {
return;
}
//if it is input with source, we pass callback in third param to be called when source is loaded
if(this.input.options.hasOwnProperty('source')) {
return this.input.value2html(this.value, this.$element[0], this.options.display);
return this.input.value2html(this.value, this.$element[0], this.options.display, response);
//if display method defined --> use it
} else if(typeof this.options.display === 'function') {
return this.options.display.call(this.$element[0], this.value);
return this.options.display.call(this.$element[0], this.value, response);
//else use input's original value2html() method
} else {
return this.input.value2html(this.value, this.$element[0]);
@ -189,12 +183,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
//disabled
if(key === 'disabled') {
if(value) {
this.disable();
} else {
this.enable();
}
return;
return value ? this.disable() : this.enable();
}
//value
@ -206,6 +195,12 @@ Makes editable any HTML element on the page. Applied as jQuery method.
if(this.container) {
this.container.option(key, value);
}
//pass option to input directly (as it points to the same in form)
if(this.input.option) {
this.input.option(key, value);
}
},
/*
@ -247,7 +242,8 @@ Makes editable any HTML element on the page. Applied as jQuery method.
//init editableContainer: popover, tooltip, inline, etc..
if(!this.container) {
var containerOptions = $.extend({}, this.options, {
value: this.value
value: this.value,
input: this.input //pass input to form (as it is already created)
});
this.$element.editableContainer(containerOptions);
this.$element.on("save.internal", $.proxy(this.save, this));
@ -294,8 +290,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
this.$element.removeClass('editable-unsaved');
}
// this.hide();
this.setValue(params.newValue);
this.setValue(params.newValue, false, params.response);
/**
Fired when new value was submitted. You can use <code>$(this).data('editable')</code> to access to editable instance
@ -307,13 +302,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
@param {Object} params.response ajax response
@example
$('#username').on('save', function(e, params) {
//assuming server response: '{success: true}'
var pk = $(this).data('editable').options.pk;
if(params.response && params.response.success) {
alert('value: ' + params.newValue + ' with pk: ' + pk + ' saved!');
} else {
alert('error!');
}
alert('Saved value: ' + params.newValue);
});
**/
//event itself is triggered by editableContainer. Description here is only for documentation
@ -331,7 +320,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
@param {mixed} value new value
@param {boolean} convertStr whether to convert value from string to internal format
**/
setValue: function(value, convertStr) {
setValue: function(value, convertStr, response) {
if(convertStr) {
this.value = this.input.str2value(value);
} else {
@ -340,7 +329,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
if(this.container) {
this.container.option('value', this.value);
}
$.when(this.render())
$.when(this.render(response))
.then($.proxy(function() {
this.handleEmpty();
}, this));
@ -354,7 +343,28 @@ Makes editable any HTML element on the page. Applied as jQuery method.
if(this.container) {
this.container.activate();
}
}
},
/**
Removes editable feature from element
@method destroy()
**/
destroy: function() {
if(this.container) {
this.container.destroy();
}
if(this.options.toggle !== 'manual') {
this.$element.removeClass('editable-click');
this.$element.off(this.options.toggle + '.editable');
}
this.$element.off("save.internal");
this.$element.removeClass('editable');
this.$element.removeClass('editable-open');
this.$element.removeData('editable');
}
};
/* EDITABLE PLUGIN DEFINITION
@ -540,7 +550,7 @@ Makes editable any HTML element on the page. Applied as jQuery method.
**/
autotext: 'auto',
/**
Initial value of input. Taken from <code>data-value</code> or element's text.
Initial value of input. If not set, taken from element's text.
@property value
@type mixed
@ -549,10 +559,21 @@ Makes editable any HTML element on the page. Applied as jQuery method.
value: null,
/**
Callback to perform custom displaying of value in element's text.
If <code>null</code>, default input's value2html() will be called.
If <code>false</code>, no displaying methods will be called, element's text will no change.
If `null`, default input's display used.
If `false`, no displaying methods will be called, element's text will never change.
Runs under element's scope.
Second parameter __sourceData__ is passed for inputs with source (select, checklist).
_Parameters:_
* `value` current value to be displayed
* `response` server response (if display called after ajax submit), since 1.4.0
For **inputs with source** (select, checklist) parameters are different:
* `value` current value to be displayed
* `sourceData` array of items for current input (e.g. dropdown items)
* `response` server response (if display called after ajax submit), since 1.4.0
To get currently selected items use `$.fn.editableutils.itemsByValue(value, sourceData)`.
@property display
@type function|boolean
@ -560,8 +581,16 @@ Makes editable any HTML element on the page. Applied as jQuery method.
@since 1.2.0
@example
display: function(value, sourceData) {
var escapedValue = $('<div>').text(value).html();
$(this).html('<b>'+escapedValue+'</b>');
//display checklist as comma-separated values
var html = [],
checked = $.fn.editableutils.itemsByValue(value, sourceData);
if(checked.length) {
$.each(checked, function(i, v) { html.push($.fn.editableutils.escape(v.text)); });
$(this).html(html.join(', '));
} else {
$(this).empty();
}
}
**/
display: null

BIN
src/img/clear.png Normal file

Binary file not shown.

After

(image error) Size: 509 B

Before

(image error) Size: 1.8 KiB

After

(image error) Size: 1.8 KiB

@ -36,7 +36,7 @@ $(function(){
@method render()
**/
render: function() {
Address.superclass.render.call(this);
this.$input = this.$tpl.find('input');
},
/**
@ -111,9 +111,9 @@ $(function(){
@param {mixed} value
**/
value2input: function(value) {
this.$input.find('input[name="city"]').val(value.city);
this.$input.find('input[name="street"]').val(value.street);
this.$input.find('input[name="building"]').val(value.building);
this.$input.filter('[name="city"]').val(value.city);
this.$input.filter('[name="street"]').val(value.street);
this.$input.filter('[name="building"]').val(value.building);
},
/**
@ -123,9 +123,9 @@ $(function(){
**/
input2value: function() {
return {
city: this.$input.find('input[name="city"]').val(),
street: this.$input.find('input[name="street"]').val(),
building: this.$input.find('input[name="building"]').val()
city: this.$input.filter('[name="city"]').val(),
street: this.$input.filter('[name="street"]').val(),
building: this.$input.filter('[name="building"]').val()
};
},
@ -135,7 +135,7 @@ $(function(){
@method activate()
**/
activate: function() {
this.$input.find('input[name="city"]').focus();
this.$input.filter('[name="city"]').focus();
},
/**
@ -144,7 +144,7 @@ $(function(){
@method autosubmit()
**/
autosubmit: function() {
this.$input.find('input[type="text"]').keydown(function (e) {
this.$input.keydown(function (e) {
if (e.which === 13) {
$(this).closest('form').submit();
}
@ -153,11 +153,11 @@ $(function(){
});
Address.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
tpl: '<div><label><span>City: </span><input type="text" name="city" class="input-small"></label></div>'+
'<div><label><span>Street: </span><input type="text" name="street" class="input-small"></label></div>'+
'<div><label><span>Building: </span><input type="text" name="building" class="input-mini"></label></div>',
tpl: '<div class="editable-address"><label><span>City: </span><input type="text" name="city" class="input-small"></label></div>'+
'<div class="editable-address"><label><span>Street: </span><input type="text" name="street" class="input-small"></label></div>'+
'<div class="editable-address"><label><span>Building: </span><input type="text" name="building" class="input-mini"></label></div>',
inputclass: 'editable-address'
inputclass: ''
});
$.fn.editabletypes.address = Address;

@ -0,0 +1,102 @@
ul.wysihtml5-toolbar {
margin: 0;
padding: 0;
display: block;
}
ul.wysihtml5-toolbar::after {
clear: both;
display: table;
content: "";
}
ul.wysihtml5-toolbar > li {
float: left;
display: list-item;
list-style: none;
margin: 0 5px 10px 0;
}
ul.wysihtml5-toolbar a[data-wysihtml5-command=bold] {
font-weight: bold;
}
ul.wysihtml5-toolbar a[data-wysihtml5-command=italic] {
font-style: italic;
}
ul.wysihtml5-toolbar a[data-wysihtml5-command=underline] {
text-decoration: underline;
}
ul.wysihtml5-toolbar a.btn.wysihtml5-command-active {
background-image: none;
-webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);
-moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);
background-color: #E6E6E6;
background-color: #D9D9D9;
outline: 0;
}
ul.wysihtml5-commands-disabled .dropdown-menu {
display: none !important;
}
ul.wysihtml5-toolbar div.wysihtml5-colors {
display:block;
width: 50px;
height: 20px;
margin-top: 2px;
margin-left: 5px;
position: absolute;
pointer-events: none;
}
ul.wysihtml5-toolbar a.wysihtml5-colors-title {
padding-left: 70px;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="black"] {
background: black !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="silver"] {
background: silver !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="gray"] {
background: gray !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="maroon"] {
background: maroon !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="red"] {
background: red !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="purple"] {
background: purple !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="green"] {
background: green !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="olive"] {
background: olive !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="navy"] {
background: navy !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="blue"] {
background: blue !important;
}
ul.wysihtml5-toolbar div[data-wysihtml5-command-value="orange"] {
background: orange !important;
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -0,0 +1,261 @@
/*
wysihtml5 v0.3.0
https://github.com/xing/wysihtml5
Author: Christopher Blum (https://github.com/tiff)
Copyright (C) 2012 XING AG
Licensed under the MIT license (MIT)
Rangy, a cross-browser JavaScript range and selection library
http://code.google.com/p/rangy/
Copyright 2011, Tim Down
Licensed under the MIT license.
Version: 1.2.2
Build date: 13 November 2011
*/
var wysihtml5={version:"0.3.0",commands:{},dom:{},quirks:{},toolbar:{},lang:{},selection:{},views:{},INVISIBLE_SPACE:"\ufeff",EMPTY_FUNCTION:function(){},ELEMENT_NODE:1,TEXT_NODE:3,BACKSPACE_KEY:8,ENTER_KEY:13,ESCAPE_KEY:27,SPACE_KEY:32,DELETE_KEY:46};
window.rangy=function(){function b(a,b){var c=typeof a[b];return c==k||!!(c==h&&a[b])||"unknown"==c}function c(a,b){return!!(typeof a[b]==h&&a[b])}function a(a,b){return typeof a[b]!=j}function d(a){return function(b,c){for(var d=c.length;d--;)if(!a(b,c[d]))return!1;return!0}}function e(a){return a&&m(a,r)&&x(a,q)}function f(a){window.alert("Rangy not supported in your browser. Reason: "+a);o.initialized=!0;o.supported=!1}function g(){if(!o.initialized){var a,d=!1,h=!1;b(document,"createRange")&&
(a=document.createRange(),m(a,p)&&x(a,n)&&(d=!0),a.detach());if((a=c(document,"body")?document.body:document.getElementsByTagName("body")[0])&&b(a,"createTextRange"))a=a.createTextRange(),e(a)&&(h=!0);!d&&!h&&f("Neither Range nor TextRange are implemented");o.initialized=!0;o.features={implementsDomRange:d,implementsTextRange:h};d=w.concat(z);h=0;for(a=d.length;h<a;++h)try{d[h](o)}catch(j){c(window,"console")&&b(window.console,"log")&&window.console.log("Init listener threw an exception. Continuing.",
j)}}}function i(a){this.name=a;this.supported=this.initialized=!1}var h="object",k="function",j="undefined",n="startContainer startOffset endContainer endOffset collapsed commonAncestorContainer START_TO_START START_TO_END END_TO_START END_TO_END".split(" "),p="setStart setStartBefore setStartAfter setEnd setEndBefore setEndAfter collapse selectNode selectNodeContents compareBoundaryPoints deleteContents extractContents cloneContents insertNode surroundContents cloneRange toString detach".split(" "),
q="boundingHeight boundingLeft boundingTop boundingWidth htmlText text".split(" "),r="collapse compareEndPoints duplicate getBookmark moveToBookmark moveToElementText parentElement pasteHTML select setEndPoint getBoundingClientRect".split(" "),m=d(b),s=d(c),x=d(a),o={version:"1.2.2",initialized:!1,supported:!0,util:{isHostMethod:b,isHostObject:c,isHostProperty:a,areHostMethods:m,areHostObjects:s,areHostProperties:x,isTextRange:e},features:{},modules:{},config:{alertOnWarn:!1,preferTextRange:!1}};
o.fail=f;o.warn=function(a){a="Rangy warning: "+a;o.config.alertOnWarn?window.alert(a):typeof window.console!=j&&typeof window.console.log!=j&&window.console.log(a)};({}).hasOwnProperty?o.util.extend=function(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c])}:f("hasOwnProperty not supported");var z=[],w=[];o.init=g;o.addInitListener=function(a){o.initialized?a(o):z.push(a)};var y=[];o.addCreateMissingNativeApiListener=function(a){y.push(a)};o.createMissingNativeApi=function(a){a=a||window;g();
for(var b=0,c=y.length;b<c;++b)y[b](a)};i.prototype.fail=function(a){this.initialized=!0;this.supported=!1;throw Error("Module '"+this.name+"' failed to load: "+a);};i.prototype.warn=function(a){o.warn("Module "+this.name+": "+a)};i.prototype.createError=function(a){return Error("Error in Rangy "+this.name+" module: "+a)};o.createModule=function(a,b){var c=new i(a);o.modules[a]=c;w.push(function(a){b(a,c);c.initialized=!0;c.supported=!0})};o.requireModules=function(a){for(var b=0,c=a.length,d,h;b<
c;++b){h=a[b];d=o.modules[h];if(!d||!(d instanceof i))throw Error("Module '"+h+"' not found");if(!d.supported)throw Error("Module '"+h+"' not supported");}};var A=!1,s=function(){A||(A=!0,o.initialized||g())};if(typeof window==j)f("No window found");else if(typeof document==j)f("No document found");else return b(document,"addEventListener")&&document.addEventListener("DOMContentLoaded",s,!1),b(window,"addEventListener")?window.addEventListener("load",s,!1):b(window,"attachEvent")?window.attachEvent("onload",
s):f("Window does not have required addEventListener or attachEvent method"),o}();
rangy.createModule("DomUtil",function(b,c){function a(a){for(var b=0;a=a.previousSibling;)b++;return b}function d(a,b){var c=[],d;for(d=a;d;d=d.parentNode)c.push(d);for(d=b;d;d=d.parentNode)if(m(c,d))return d;return null}function e(a,b,c){for(c=c?a:a.parentNode;c;){a=c.parentNode;if(a===b)return c;c=a}return null}function f(a){a=a.nodeType;return 3==a||4==a||8==a}function g(a,b){var c=b.nextSibling,d=b.parentNode;c?d.insertBefore(a,c):d.appendChild(a);return a}function i(a){if(9==a.nodeType)return a;
if(typeof a.ownerDocument!=p)return a.ownerDocument;if(typeof a.document!=p)return a.document;if(a.parentNode)return i(a.parentNode);throw Error("getDocument: no document found for node");}function h(a){return!a?"[No node]":f(a)?'"'+a.data+'"':1==a.nodeType?"<"+a.nodeName+(a.id?' id="'+a.id+'"':"")+">["+a.childNodes.length+"]":a.nodeName}function k(a){this._next=this.root=a}function j(a,b){this.node=a;this.offset=b}function n(a){this.code=this[a];this.codeName=a;this.message="DOMException: "+this.codeName}
var p="undefined",q=b.util;q.areHostMethods(document,["createDocumentFragment","createElement","createTextNode"])||c.fail("document missing a Node creation method");q.isHostMethod(document,"getElementsByTagName")||c.fail("document missing getElementsByTagName method");var r=document.createElement("div");q.areHostMethods(r,["insertBefore","appendChild","cloneNode"])||c.fail("Incomplete Element implementation");q.isHostProperty(r,"innerHTML")||c.fail("Element is missing innerHTML property");r=document.createTextNode("test");
q.areHostMethods(r,["splitText","deleteData","insertData","appendData","cloneNode"])||c.fail("Incomplete Text Node implementation");var m=function(a,b){for(var c=a.length;c--;)if(a[c]===b)return!0;return!1};k.prototype={_current:null,hasNext:function(){return!!this._next},next:function(){var a=this._current=this._next,b;if(this._current){b=a.firstChild;if(!b)for(b=null;a!==this.root&&!(b=a.nextSibling);)a=a.parentNode;this._next=b}return this._current},detach:function(){this._current=this._next=this.root=
null}};j.prototype={equals:function(a){return this.node===a.node&this.offset==a.offset},inspect:function(){return"[DomPosition("+h(this.node)+":"+this.offset+")]"}};n.prototype={INDEX_SIZE_ERR:1,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INVALID_STATE_ERR:11};n.prototype.toString=function(){return this.message};b.dom={arrayContains:m,isHtmlNamespace:function(a){var b;return typeof a.namespaceURI==p||null===(b=a.namespaceURI)||"http://www.w3.org/1999/xhtml"==
b},parentElement:function(a){a=a.parentNode;return 1==a.nodeType?a:null},getNodeIndex:a,getNodeLength:function(a){var b;return f(a)?a.length:(b=a.childNodes)?b.length:0},getCommonAncestor:d,isAncestorOf:function(a,b,c){for(b=c?b:b.parentNode;b;){if(b===a)return!0;b=b.parentNode}return!1},getClosestAncestorIn:e,isCharacterDataNode:f,insertAfter:g,splitDataNode:function(a,b){var c=a.cloneNode(!1);c.deleteData(0,b);a.deleteData(b,a.length-b);g(c,a);return c},getDocument:i,getWindow:function(a){a=i(a);
if(typeof a.defaultView!=p)return a.defaultView;if(typeof a.parentWindow!=p)return a.parentWindow;throw Error("Cannot get a window object for node");},getIframeWindow:function(a){if(typeof a.contentWindow!=p)return a.contentWindow;if(typeof a.contentDocument!=p)return a.contentDocument.defaultView;throw Error("getIframeWindow: No Window object found for iframe element");},getIframeDocument:function(a){if(typeof a.contentDocument!=p)return a.contentDocument;if(typeof a.contentWindow!=p)return a.contentWindow.document;
throw Error("getIframeWindow: No Document object found for iframe element");},getBody:function(a){return q.isHostObject(a,"body")?a.body:a.getElementsByTagName("body")[0]},getRootContainer:function(a){for(var b;b=a.parentNode;)a=b;return a},comparePoints:function(b,c,h,j){var k;if(b==h)return c===j?0:c<j?-1:1;if(k=e(h,b,!0))return c<=a(k)?-1:1;if(k=e(b,h,!0))return a(k)<j?-1:1;c=d(b,h);b=b===c?c:e(b,c,!0);h=h===c?c:e(h,c,!0);if(b===h)throw Error("comparePoints got to case 4 and childA and childB are the same!");
for(c=c.firstChild;c;){if(c===b)return-1;if(c===h)return 1;c=c.nextSibling}throw Error("Should not be here!");},inspectNode:h,fragmentFromNodeChildren:function(a){for(var b=i(a).createDocumentFragment(),c;c=a.firstChild;)b.appendChild(c);return b},createIterator:function(a){return new k(a)},DomPosition:j};b.DOMException=n});
rangy.createModule("DomRange",function(b){function c(a,b){return 3!=a.nodeType&&(l.isAncestorOf(a,b.startContainer,!0)||l.isAncestorOf(a,b.endContainer,!0))}function a(a){return l.getDocument(a.startContainer)}function d(a,b,c){if(b=a._listeners[b])for(var d=0,h=b.length;d<h;++d)b[d].call(a,{target:a,args:c})}function e(a){return new u(a.parentNode,l.getNodeIndex(a))}function f(a){return new u(a.parentNode,l.getNodeIndex(a)+1)}function g(a,b,c){var d=11==a.nodeType?a.firstChild:a;l.isCharacterDataNode(b)?
c==b.length?l.insertAfter(a,b):b.parentNode.insertBefore(a,0==c?b:l.splitDataNode(b,c)):c>=b.childNodes.length?b.appendChild(a):b.insertBefore(a,b.childNodes[c]);return d}function i(b){for(var c,d,h=a(b.range).createDocumentFragment();d=b.next();){c=b.isPartiallySelectedSubtree();d=d.cloneNode(!c);c&&(c=b.getSubtreeIterator(),d.appendChild(i(c)),c.detach(!0));if(10==d.nodeType)throw new B("HIERARCHY_REQUEST_ERR");h.appendChild(d)}return h}function h(a,b,c){for(var d,e,c=c||{stop:!1};d=a.next();)if(a.isPartiallySelectedSubtree())if(!1===
b(d)){c.stop=!0;break}else{if(d=a.getSubtreeIterator(),h(d,b,c),d.detach(!0),c.stop)break}else for(d=l.createIterator(d);e=d.next();)if(!1===b(e)){c.stop=!0;return}}function k(a){for(var b;a.next();)a.isPartiallySelectedSubtree()?(b=a.getSubtreeIterator(),k(b),b.detach(!0)):a.remove()}function j(b){for(var c,d=a(b.range).createDocumentFragment(),h;c=b.next();){b.isPartiallySelectedSubtree()?(c=c.cloneNode(!1),h=b.getSubtreeIterator(),c.appendChild(j(h)),h.detach(!0)):b.remove();if(10==c.nodeType)throw new B("HIERARCHY_REQUEST_ERR");
d.appendChild(c)}return d}function n(a,b,c){var d=!(!b||!b.length),e,j=!!c;d&&(e=RegExp("^("+b.join("|")+")$"));var k=[];h(new q(a,!1),function(a){(!d||e.test(a.nodeType))&&(!j||c(a))&&k.push(a)});return k}function p(a){return"["+("undefined"==typeof a.getName?"Range":a.getName())+"("+l.inspectNode(a.startContainer)+":"+a.startOffset+", "+l.inspectNode(a.endContainer)+":"+a.endOffset+")]"}function q(a,b){this.range=a;this.clonePartiallySelectedTextNodes=b;if(!a.collapsed){this.sc=a.startContainer;
this.so=a.startOffset;this.ec=a.endContainer;this.eo=a.endOffset;var c=a.commonAncestorContainer;this.sc===this.ec&&l.isCharacterDataNode(this.sc)?(this.isSingleCharacterDataNode=!0,this._first=this._last=this._next=this.sc):(this._first=this._next=this.sc===c&&!l.isCharacterDataNode(this.sc)?this.sc.childNodes[this.so]:l.getClosestAncestorIn(this.sc,c,!0),this._last=this.ec===c&&!l.isCharacterDataNode(this.ec)?this.ec.childNodes[this.eo-1]:l.getClosestAncestorIn(this.ec,c,!0))}}function r(a){this.code=
this[a];this.codeName=a;this.message="RangeException: "+this.codeName}function m(a,b,c){this.nodes=n(a,b,c);this._next=this.nodes[0];this._position=0}function s(a){return function(b,c){for(var d,h=c?b:b.parentNode;h;){d=h.nodeType;if(l.arrayContains(a,d))return h;h=h.parentNode}return null}}function x(a,b){if($(a,b))throw new r("INVALID_NODE_TYPE_ERR");}function o(a){if(!a.startContainer)throw new B("INVALID_STATE_ERR");}function z(a,b){if(!l.arrayContains(b,a.nodeType))throw new r("INVALID_NODE_TYPE_ERR");
}function w(a,b){if(0>b||b>(l.isCharacterDataNode(a)?a.length:a.childNodes.length))throw new B("INDEX_SIZE_ERR");}function y(a,b){if(O(a,!0)!==O(b,!0))throw new B("WRONG_DOCUMENT_ERR");}function A(a){if(aa(a,!0))throw new B("NO_MODIFICATION_ALLOWED_ERR");}function t(a,b){if(!a)throw new B(b);}function v(a){o(a);if(!l.arrayContains(G,a.startContainer.nodeType)&&!O(a.startContainer,!0)||!l.arrayContains(G,a.endContainer.nodeType)&&!O(a.endContainer,!0)||!(a.startOffset<=(l.isCharacterDataNode(a.startContainer)?
a.startContainer.length:a.startContainer.childNodes.length))||!(a.endOffset<=(l.isCharacterDataNode(a.endContainer)?a.endContainer.length:a.endContainer.childNodes.length)))throw Error("Range error: Range is no longer valid after DOM mutation ("+a.inspect()+")");}function D(){}function K(a){a.START_TO_START=Q;a.START_TO_END=U;a.END_TO_END=ba;a.END_TO_START=V;a.NODE_BEFORE=W;a.NODE_AFTER=X;a.NODE_BEFORE_AND_AFTER=Y;a.NODE_INSIDE=R}function F(a){K(a);K(a.prototype)}function E(a,b){return function(){v(this);
var c=this.startContainer,d=this.startOffset,e=this.commonAncestorContainer,j=new q(this,!0);c!==e&&(c=l.getClosestAncestorIn(c,e,!0),d=f(c),c=d.node,d=d.offset);h(j,A);j.reset();e=a(j);j.detach();b(this,c,d,c,d);return e}}function I(a,d,h){function g(a,b){return function(c){o(this);z(c,L);z(M(c),G);c=(a?e:f)(c);(b?i:n)(this,c.node,c.offset)}}function i(a,b,c){var h=a.endContainer,e=a.endOffset;if(b!==a.startContainer||c!==a.startOffset){if(M(b)!=M(h)||1==l.comparePoints(b,c,h,e))h=b,e=c;d(a,b,c,
h,e)}}function n(a,b,c){var h=a.startContainer,e=a.startOffset;if(b!==a.endContainer||c!==a.endOffset){if(M(b)!=M(h)||-1==l.comparePoints(b,c,h,e))h=b,e=c;d(a,h,e,b,c)}}a.prototype=new D;b.util.extend(a.prototype,{setStart:function(a,b){o(this);x(a,!0);w(a,b);i(this,a,b)},setEnd:function(a,b){o(this);x(a,!0);w(a,b);n(this,a,b)},setStartBefore:g(!0,!0),setStartAfter:g(!1,!0),setEndBefore:g(!0,!1),setEndAfter:g(!1,!1),collapse:function(a){v(this);a?d(this,this.startContainer,this.startOffset,this.startContainer,
this.startOffset):d(this,this.endContainer,this.endOffset,this.endContainer,this.endOffset)},selectNodeContents:function(a){o(this);x(a,!0);d(this,a,0,a,l.getNodeLength(a))},selectNode:function(a){o(this);x(a,!1);z(a,L);var b=e(a),a=f(a);d(this,b.node,b.offset,a.node,a.offset)},extractContents:E(j,d),deleteContents:E(k,d),canSurroundContents:function(){v(this);A(this.startContainer);A(this.endContainer);var a=new q(this,!0),b=a._first&&c(a._first,this)||a._last&&c(a._last,this);a.detach();return!b},
detach:function(){h(this)},splitBoundaries:function(){v(this);var a=this.startContainer,b=this.startOffset,c=this.endContainer,h=this.endOffset,e=a===c;l.isCharacterDataNode(c)&&(0<h&&h<c.length)&&l.splitDataNode(c,h);l.isCharacterDataNode(a)&&(0<b&&b<a.length)&&(a=l.splitDataNode(a,b),e?(h-=b,c=a):c==a.parentNode&&h>=l.getNodeIndex(a)&&h++,b=0);d(this,a,b,c,h)},normalizeBoundaries:function(){v(this);var a=this.startContainer,b=this.startOffset,c=this.endContainer,h=this.endOffset,e=function(a){var b=
a.nextSibling;b&&b.nodeType==a.nodeType&&(c=a,h=a.length,a.appendData(b.data),b.parentNode.removeChild(b))},j=function(d){var e=d.previousSibling;if(e&&e.nodeType==d.nodeType){a=d;var j=d.length;b=e.length;d.insertData(0,e.data);e.parentNode.removeChild(e);a==c?(h+=b,c=a):c==d.parentNode&&(e=l.getNodeIndex(d),h==e?(c=d,h=j):h>e&&h--)}},k=!0;l.isCharacterDataNode(c)?c.length==h&&e(c):(0<h&&(k=c.childNodes[h-1])&&l.isCharacterDataNode(k)&&e(k),k=!this.collapsed);k?l.isCharacterDataNode(a)?0==b&&j(a):
b<a.childNodes.length&&(e=a.childNodes[b])&&l.isCharacterDataNode(e)&&j(e):(a=c,b=h);d(this,a,b,c,h)},collapseToPoint:function(a,b){o(this);x(a,!0);w(a,b);(a!==this.startContainer||b!==this.startOffset||a!==this.endContainer||b!==this.endOffset)&&d(this,a,b,a,b)}});F(a)}function N(a){a.collapsed=a.startContainer===a.endContainer&&a.startOffset===a.endOffset;a.commonAncestorContainer=a.collapsed?a.startContainer:l.getCommonAncestor(a.startContainer,a.endContainer)}function J(a,b,c,h,e){var j=a.startContainer!==
b||a.startOffset!==c,k=a.endContainer!==h||a.endOffset!==e;a.startContainer=b;a.startOffset=c;a.endContainer=h;a.endOffset=e;N(a);d(a,"boundarychange",{startMoved:j,endMoved:k})}function C(a){this.startContainer=a;this.startOffset=0;this.endContainer=a;this.endOffset=0;this._listeners={boundarychange:[],detach:[]};N(this)}b.requireModules(["DomUtil"]);var l=b.dom,u=l.DomPosition,B=b.DOMException;q.prototype={_current:null,_next:null,_first:null,_last:null,isSingleCharacterDataNode:!1,reset:function(){this._current=
null;this._next=this._first},hasNext:function(){return!!this._next},next:function(){var a=this._current=this._next;a&&(this._next=a!==this._last?a.nextSibling:null,l.isCharacterDataNode(a)&&this.clonePartiallySelectedTextNodes&&(a===this.ec&&(a=a.cloneNode(!0)).deleteData(this.eo,a.length-this.eo),this._current===this.sc&&(a=a.cloneNode(!0)).deleteData(0,this.so)));return a},remove:function(){var a=this._current,b,c;l.isCharacterDataNode(a)&&(a===this.sc||a===this.ec)?(b=a===this.sc?this.so:0,c=a===
this.ec?this.eo:a.length,b!=c&&a.deleteData(b,c-b)):a.parentNode&&a.parentNode.removeChild(a)},isPartiallySelectedSubtree:function(){return c(this._current,this.range)},getSubtreeIterator:function(){var b;if(this.isSingleCharacterDataNode)b=this.range.cloneRange(),b.collapse();else{b=new C(a(this.range));var c=this._current,d=c,h=0,e=c,j=l.getNodeLength(c);l.isAncestorOf(c,this.sc,!0)&&(d=this.sc,h=this.so);l.isAncestorOf(c,this.ec,!0)&&(e=this.ec,j=this.eo);J(b,d,h,e,j)}return new q(b,this.clonePartiallySelectedTextNodes)},
detach:function(a){a&&this.range.detach();this.range=this._current=this._next=this._first=this._last=this.sc=this.so=this.ec=this.eo=null}};r.prototype={BAD_BOUNDARYPOINTS_ERR:1,INVALID_NODE_TYPE_ERR:2};r.prototype.toString=function(){return this.message};m.prototype={_current:null,hasNext:function(){return!!this._next},next:function(){this._current=this._next;this._next=this.nodes[++this._position];return this._current},detach:function(){this._current=this._next=this.nodes=null}};var L=[1,3,4,5,
7,8,10],G=[2,9,11],P=[1,3,4,5,7,8,10,11],H=[1,3,4,5,7,8],M=l.getRootContainer,O=s([9,11]),aa=s([5,6,10,12]),$=s([6,10,12]),Z=document.createElement("style"),S=!1;try{Z.innerHTML="<b>x</b>",S=3==Z.firstChild.nodeType}catch(ca){}b.features.htmlParsingConforms=S;var T="startContainer startOffset endContainer endOffset collapsed commonAncestorContainer".split(" "),Q=0,U=1,ba=2,V=3,W=0,X=1,Y=2,R=3;D.prototype={attachListener:function(a,b){this._listeners[a].push(b)},compareBoundaryPoints:function(a,b){v(this);
y(this.startContainer,b.startContainer);var c=a==V||a==Q?"start":"end",d=a==U||a==Q?"start":"end";return l.comparePoints(this[c+"Container"],this[c+"Offset"],b[d+"Container"],b[d+"Offset"])},insertNode:function(a){v(this);z(a,P);A(this.startContainer);if(l.isAncestorOf(a,this.startContainer,!0))throw new B("HIERARCHY_REQUEST_ERR");this.setStartBefore(g(a,this.startContainer,this.startOffset))},cloneContents:function(){v(this);var b,c;if(this.collapsed)return a(this).createDocumentFragment();if(this.startContainer===
this.endContainer&&l.isCharacterDataNode(this.startContainer))return b=this.startContainer.cloneNode(!0),b.data=b.data.slice(this.startOffset,this.endOffset),c=a(this).createDocumentFragment(),c.appendChild(b),c;c=new q(this,!0);b=i(c);c.detach();return b},canSurroundContents:function(){v(this);A(this.startContainer);A(this.endContainer);var a=new q(this,!0),b=a._first&&c(a._first,this)||a._last&&c(a._last,this);a.detach();return!b},surroundContents:function(a){z(a,H);if(!this.canSurroundContents())throw new r("BAD_BOUNDARYPOINTS_ERR");
var b=this.extractContents();if(a.hasChildNodes())for(;a.lastChild;)a.removeChild(a.lastChild);g(a,this.startContainer,this.startOffset);a.appendChild(b);this.selectNode(a)},cloneRange:function(){v(this);for(var b=new C(a(this)),c=T.length,d;c--;)d=T[c],b[d]=this[d];return b},toString:function(){v(this);var a=this.startContainer;if(a===this.endContainer&&l.isCharacterDataNode(a))return 3==a.nodeType||4==a.nodeType?a.data.slice(this.startOffset,this.endOffset):"";var b=[],a=new q(this,!0);h(a,function(a){(3==
a.nodeType||4==a.nodeType)&&b.push(a.data)});a.detach();return b.join("")},compareNode:function(a){v(this);var b=a.parentNode,c=l.getNodeIndex(a);if(!b)throw new B("NOT_FOUND_ERR");a=this.comparePoint(b,c);b=this.comparePoint(b,c+1);return 0>a?0<b?Y:W:0<b?X:R},comparePoint:function(a,b){v(this);t(a,"HIERARCHY_REQUEST_ERR");y(a,this.startContainer);return 0>l.comparePoints(a,b,this.startContainer,this.startOffset)?-1:0<l.comparePoints(a,b,this.endContainer,this.endOffset)?1:0},createContextualFragment:S?
function(a){var b=this.startContainer,c=l.getDocument(b);if(!b)throw new B("INVALID_STATE_ERR");var d=null;1==b.nodeType?d=b:l.isCharacterDataNode(b)&&(d=l.parentElement(b));d=null===d||"HTML"==d.nodeName&&l.isHtmlNamespace(l.getDocument(d).documentElement)&&l.isHtmlNamespace(d)?c.createElement("body"):d.cloneNode(!1);d.innerHTML=a;return l.fragmentFromNodeChildren(d)}:function(b){o(this);var c=a(this).createElement("body");c.innerHTML=b;return l.fragmentFromNodeChildren(c)},toHtml:function(){v(this);
var b=a(this).createElement("div");b.appendChild(this.cloneContents());return b.innerHTML},intersectsNode:function(b,c){v(this);t(b,"NOT_FOUND_ERR");if(l.getDocument(b)!==a(this))return!1;var d=b.parentNode,h=l.getNodeIndex(b);t(d,"NOT_FOUND_ERR");var e=l.comparePoints(d,h,this.endContainer,this.endOffset),d=l.comparePoints(d,h+1,this.startContainer,this.startOffset);return c?0>=e&&0<=d:0>e&&0<d},isPointInRange:function(a,b){v(this);t(a,"HIERARCHY_REQUEST_ERR");y(a,this.startContainer);return 0<=
l.comparePoints(a,b,this.startContainer,this.startOffset)&&0>=l.comparePoints(a,b,this.endContainer,this.endOffset)},intersectsRange:function(b,c){v(this);if(a(b)!=a(this))throw new B("WRONG_DOCUMENT_ERR");var d=l.comparePoints(this.startContainer,this.startOffset,b.endContainer,b.endOffset),h=l.comparePoints(this.endContainer,this.endOffset,b.startContainer,b.startOffset);return c?0>=d&&0<=h:0>d&&0<h},intersection:function(a){if(this.intersectsRange(a)){var b=l.comparePoints(this.startContainer,
this.startOffset,a.startContainer,a.startOffset),c=l.comparePoints(this.endContainer,this.endOffset,a.endContainer,a.endOffset),d=this.cloneRange();-1==b&&d.setStart(a.startContainer,a.startOffset);1==c&&d.setEnd(a.endContainer,a.endOffset);return d}return null},union:function(a){if(this.intersectsRange(a,!0)){var b=this.cloneRange();-1==l.comparePoints(a.startContainer,a.startOffset,this.startContainer,this.startOffset)&&b.setStart(a.startContainer,a.startOffset);1==l.comparePoints(a.endContainer,
a.endOffset,this.endContainer,this.endOffset)&&b.setEnd(a.endContainer,a.endOffset);return b}throw new r("Ranges do not intersect");},containsNode:function(a,b){return b?this.intersectsNode(a,!1):this.compareNode(a)==R},containsNodeContents:function(a){return 0<=this.comparePoint(a,0)&&0>=this.comparePoint(a,l.getNodeLength(a))},containsRange:function(a){return this.intersection(a).equals(a)},containsNodeText:function(a){var b=this.cloneRange();b.selectNode(a);var c=b.getNodes([3]);return 0<c.length?
(b.setStart(c[0],0),a=c.pop(),b.setEnd(a,a.length),a=this.containsRange(b),b.detach(),a):this.containsNodeContents(a)},createNodeIterator:function(a,b){v(this);return new m(this,a,b)},getNodes:function(a,b){v(this);return n(this,a,b)},getDocument:function(){return a(this)},collapseBefore:function(a){o(this);this.setEndBefore(a);this.collapse(!1)},collapseAfter:function(a){o(this);this.setStartAfter(a);this.collapse(!0)},getName:function(){return"DomRange"},equals:function(a){return C.rangesEqual(this,
a)},inspect:function(){return p(this)}};I(C,J,function(a){o(a);a.startContainer=a.startOffset=a.endContainer=a.endOffset=null;a.collapsed=a.commonAncestorContainer=null;d(a,"detach",null);a._listeners=null});b.rangePrototype=D.prototype;C.rangeProperties=T;C.RangeIterator=q;C.copyComparisonConstants=F;C.createPrototypeRange=I;C.inspect=p;C.getRangeDocument=a;C.rangesEqual=function(a,b){return a.startContainer===b.startContainer&&a.startOffset===b.startOffset&&a.endContainer===b.endContainer&&a.endOffset===
b.endOffset};b.DomRange=C;b.RangeException=r});
rangy.createModule("WrappedRange",function(b){function c(a,b,c,d){var g=a.duplicate();g.collapse(c);var i=g.parentElement();e.isAncestorOf(b,i,!0)||(i=b);if(!i.canHaveHTML)return new f(i.parentNode,e.getNodeIndex(i));var b=e.getDocument(i).createElement("span"),r,m=c?"StartToStart":"StartToEnd";do i.insertBefore(b,b.previousSibling),g.moveToElementText(b);while(0<(r=g.compareEndPoints(m,a))&&b.previousSibling);m=b.nextSibling;if(-1==r&&m&&e.isCharacterDataNode(m)){g.setEndPoint(c?"EndToStart":"EndToEnd",
a);if(/[\r\n]/.test(m.data)){i=g.duplicate();c=i.text.replace(/\r\n/g,"\r").length;for(c=i.moveStart("character",c);-1==i.compareEndPoints("StartToEnd",i);)c++,i.moveStart("character",1)}else c=g.text.length;i=new f(m,c)}else m=(d||!c)&&b.previousSibling,i=(c=(d||c)&&b.nextSibling)&&e.isCharacterDataNode(c)?new f(c,0):m&&e.isCharacterDataNode(m)?new f(m,m.length):new f(i,e.getNodeIndex(b));b.parentNode.removeChild(b);return i}function a(a,b){var c,d,f=a.offset,g=e.getDocument(a.node),i=g.body.createTextRange(),
m=e.isCharacterDataNode(a.node);m?(c=a.node,d=c.parentNode):(c=a.node.childNodes,c=f<c.length?c[f]:null,d=a.node);g=g.createElement("span");g.innerHTML="&#feff;";c?d.insertBefore(g,c):d.appendChild(g);i.moveToElementText(g);i.collapse(!b);d.removeChild(g);if(m)i[b?"moveStart":"moveEnd"]("character",f);return i}b.requireModules(["DomUtil","DomRange"]);var d,e=b.dom,f=e.DomPosition,g=b.DomRange;if(b.features.implementsDomRange&&(!b.features.implementsTextRange||!b.config.preferTextRange))(function(){function a(b){for(var c=
j.length,d;c--;)d=j[c],b[d]=b.nativeRange[d]}var c,j=g.rangeProperties,f;d=function(b){if(!b)throw Error("Range must be specified");this.nativeRange=b;a(this)};g.createPrototypeRange(d,function(a,b,c,d,h){var e=a.endContainer!==d||a.endOffset!=h;if(a.startContainer!==b||a.startOffset!=c||e)a.setEnd(d,h),a.setStart(b,c)},function(a){a.nativeRange.detach();a.detached=!0;for(var b=j.length,c;b--;)c=j[b],a[c]=null});c=d.prototype;c.selectNode=function(b){this.nativeRange.selectNode(b);a(this)};c.deleteContents=
function(){this.nativeRange.deleteContents();a(this)};c.extractContents=function(){var b=this.nativeRange.extractContents();a(this);return b};c.cloneContents=function(){return this.nativeRange.cloneContents()};c.surroundContents=function(b){this.nativeRange.surroundContents(b);a(this)};c.collapse=function(b){this.nativeRange.collapse(b);a(this)};c.cloneRange=function(){return new d(this.nativeRange.cloneRange())};c.refresh=function(){a(this)};c.toString=function(){return this.nativeRange.toString()};
var i=document.createTextNode("test");e.getBody(document).appendChild(i);var q=document.createRange();q.setStart(i,0);q.setEnd(i,0);try{q.setStart(i,1),c.setStart=function(b,c){this.nativeRange.setStart(b,c);a(this)},c.setEnd=function(b,c){this.nativeRange.setEnd(b,c);a(this)},f=function(b){return function(c){this.nativeRange[b](c);a(this)}}}catch(r){c.setStart=function(b,c){try{this.nativeRange.setStart(b,c)}catch(d){this.nativeRange.setEnd(b,c),this.nativeRange.setStart(b,c)}a(this)},c.setEnd=function(b,
c){try{this.nativeRange.setEnd(b,c)}catch(d){this.nativeRange.setStart(b,c),this.nativeRange.setEnd(b,c)}a(this)},f=function(b,c){return function(d){try{this.nativeRange[b](d)}catch(e){this.nativeRange[c](d),this.nativeRange[b](d)}a(this)}}}c.setStartBefore=f("setStartBefore","setEndBefore");c.setStartAfter=f("setStartAfter","setEndAfter");c.setEndBefore=f("setEndBefore","setStartBefore");c.setEndAfter=f("setEndAfter","setStartAfter");q.selectNodeContents(i);c.selectNodeContents=q.startContainer==
i&&q.endContainer==i&&0==q.startOffset&&q.endOffset==i.length?function(b){this.nativeRange.selectNodeContents(b);a(this)}:function(a){this.setStart(a,0);this.setEnd(a,g.getEndOffset(a))};q.selectNodeContents(i);q.setEnd(i,3);f=document.createRange();f.selectNodeContents(i);f.setEnd(i,4);f.setStart(i,2);c.compareBoundaryPoints=-1==q.compareBoundaryPoints(q.START_TO_END,f)&1==q.compareBoundaryPoints(q.END_TO_START,f)?function(a,b){b=b.nativeRange||b;a==b.START_TO_END?a=b.END_TO_START:a==b.END_TO_START&&
(a=b.START_TO_END);return this.nativeRange.compareBoundaryPoints(a,b)}:function(a,b){return this.nativeRange.compareBoundaryPoints(a,b.nativeRange||b)};b.util.isHostMethod(q,"createContextualFragment")&&(c.createContextualFragment=function(a){return this.nativeRange.createContextualFragment(a)});e.getBody(document).removeChild(i);q.detach();f.detach()})(),b.createNativeRange=function(a){a=a||document;return a.createRange()};else if(b.features.implementsTextRange){d=function(a){this.textRange=a;this.refresh()};
d.prototype=new g(document);d.prototype.refresh=function(){var a,b,d=this.textRange;a=d.parentElement();var f=d.duplicate();f.collapse(!0);b=f.parentElement();f=d.duplicate();f.collapse(!1);d=f.parentElement();b=b==d?b:e.getCommonAncestor(b,d);b=b==a?b:e.getCommonAncestor(a,b);0==this.textRange.compareEndPoints("StartToEnd",this.textRange)?b=a=c(this.textRange,b,!0,!0):(a=c(this.textRange,b,!0,!1),b=c(this.textRange,b,!1,!1));this.setStart(a.node,a.offset);this.setEnd(b.node,b.offset)};g.copyComparisonConstants(d);
var i=function(){return this}();"undefined"==typeof i.Range&&(i.Range=d);b.createNativeRange=function(a){a=a||document;return a.body.createTextRange()}}b.features.implementsTextRange&&(d.rangeToTextRange=function(b){if(b.collapsed)return a(new f(b.startContainer,b.startOffset),!0);var c=a(new f(b.startContainer,b.startOffset),!0),d=a(new f(b.endContainer,b.endOffset),!1),b=e.getDocument(b.startContainer).body.createTextRange();b.setEndPoint("StartToStart",c);b.setEndPoint("EndToEnd",d);return b});
d.prototype.getName=function(){return"WrappedRange"};b.WrappedRange=d;b.createRange=function(a){a=a||document;return new d(b.createNativeRange(a))};b.createRangyRange=function(a){a=a||document;return new g(a)};b.createIframeRange=function(a){return b.createRange(e.getIframeDocument(a))};b.createIframeRangyRange=function(a){return b.createRangyRange(e.getIframeDocument(a))};b.addCreateMissingNativeApiListener(function(a){a=a.document;if(typeof a.createRange=="undefined")a.createRange=function(){return b.createRange(this)};
a=a=null})});
rangy.createModule("WrappedSelection",function(b,c){function a(a){return(a||window).getSelection()}function d(a){return(a||window).document.selection}function e(a,b,c){var d=c?"end":"start",c=c?"start":"end";a.anchorNode=b[d+"Container"];a.anchorOffset=b[d+"Offset"];a.focusNode=b[c+"Container"];a.focusOffset=b[c+"Offset"]}function f(a){a.anchorNode=a.focusNode=null;a.anchorOffset=a.focusOffset=0;a.rangeCount=0;a.isCollapsed=!0;a._ranges.length=0}function g(a){var c;a instanceof x?(c=a._selectionNativeRange,
c||(c=b.createNativeRange(m.getDocument(a.startContainer)),c.setEnd(a.endContainer,a.endOffset),c.setStart(a.startContainer,a.startOffset),a._selectionNativeRange=c,a.attachListener("detach",function(){this._selectionNativeRange=null}))):a instanceof o?c=a.nativeRange:b.features.implementsDomRange&&a instanceof m.getWindow(a.startContainer).Range&&(c=a);return c}function i(a){var b=a.getNodes(),c;a:if(!b.length||1!=b[0].nodeType)c=!1;else{c=1;for(var d=b.length;c<d;++c)if(!m.isAncestorOf(b[0],b[c])){c=
!1;break a}c=!0}if(!c)throw Error("getSingleElementFromRange: range "+a.inspect()+" did not consist of a single element");return b[0]}function h(a,b){var c=new o(b);a._ranges=[c];e(a,c,!1);a.rangeCount=1;a.isCollapsed=c.collapsed}function k(a){a._ranges.length=0;if("None"==a.docSelection.type)f(a);else{var c=a.docSelection.createRange();if(c&&"undefined"!=typeof c.text)h(a,c);else{a.rangeCount=c.length;for(var d,j=m.getDocument(c.item(0)),k=0;k<a.rangeCount;++k)d=b.createRange(j),d.selectNode(c.item(k)),
a._ranges.push(d);a.isCollapsed=1==a.rangeCount&&a._ranges[0].collapsed;e(a,a._ranges[a.rangeCount-1],!1)}}}function j(a,b){for(var c=a.docSelection.createRange(),d=i(b),e=m.getDocument(c.item(0)),e=m.getBody(e).createControlRange(),h=0,j=c.length;h<j;++h)e.add(c.item(h));try{e.add(d)}catch(f){throw Error("addRange(): Element within the specified Range could not be added to control selection (does it have layout?)");}e.select();k(a)}function n(a,b,c){this.nativeSelection=a;this.docSelection=b;this._ranges=
[];this.win=c;this.refresh()}function p(a,b){for(var c=m.getDocument(b[0].startContainer),c=m.getBody(c).createControlRange(),d=0,e;d<rangeCount;++d){e=i(b[d]);try{c.add(e)}catch(h){throw Error("setRanges(): Element within the one of the specified Ranges could not be added to control selection (does it have layout?)");}}c.select();k(a)}function q(a,b){if(a.anchorNode&&m.getDocument(a.anchorNode)!==m.getDocument(b))throw new z("WRONG_DOCUMENT_ERR");}function r(a){var b=[],c=new w(a.anchorNode,a.anchorOffset),
d=new w(a.focusNode,a.focusOffset),e="function"==typeof a.getName?a.getName():"Selection";if("undefined"!=typeof a.rangeCount)for(var h=0,j=a.rangeCount;h<j;++h)b[h]=x.inspect(a.getRangeAt(h));return"["+e+"(Ranges: "+b.join(", ")+")(anchor: "+c.inspect()+", focus: "+d.inspect()+"]"}b.requireModules(["DomUtil","DomRange","WrappedRange"]);b.config.checkSelectionRanges=!0;var m=b.dom,s=b.util,x=b.DomRange,o=b.WrappedRange,z=b.DOMException,w=m.DomPosition,y,A,t=b.util.isHostMethod(window,"getSelection"),
v=b.util.isHostObject(document,"selection"),D=v&&(!t||b.config.preferTextRange);D?(y=d,b.isSelectionValid=function(a){var a=(a||window).document,b=a.selection;return"None"!=b.type||m.getDocument(b.createRange().parentElement())==a}):t?(y=a,b.isSelectionValid=function(){return!0}):c.fail("Neither document.selection or window.getSelection() detected.");b.getNativeSelection=y;var t=y(),K=b.createNativeRange(document),F=m.getBody(document),E=s.areHostObjects(t,s.areHostProperties(t,["anchorOffset","focusOffset"]));
b.features.selectionHasAnchorAndFocus=E;var I=s.isHostMethod(t,"extend");b.features.selectionHasExtend=I;var N="number"==typeof t.rangeCount;b.features.selectionHasRangeCount=N;var J=!1,C=!0;s.areHostMethods(t,["addRange","getRangeAt","removeAllRanges"])&&("number"==typeof t.rangeCount&&b.features.implementsDomRange)&&function(){var a=document.createElement("iframe");F.appendChild(a);var b=m.getIframeDocument(a);b.open();b.write("<html><head></head><body>12</body></html>");b.close();var c=m.getIframeWindow(a).getSelection(),
d=b.documentElement.lastChild.firstChild,b=b.createRange();b.setStart(d,1);b.collapse(true);c.addRange(b);C=c.rangeCount==1;c.removeAllRanges();var e=b.cloneRange();b.setStart(d,0);e.setEnd(d,2);c.addRange(b);c.addRange(e);J=c.rangeCount==2;b.detach();e.detach();F.removeChild(a)}();b.features.selectionSupportsMultipleRanges=J;b.features.collapsedNonEditableSelectionsSupported=C;var l=!1,u;F&&s.isHostMethod(F,"createControlRange")&&(u=F.createControlRange(),s.areHostProperties(u,["item","add"])&&(l=
!0));b.features.implementsControlRange=l;A=E?function(a){return a.anchorNode===a.focusNode&&a.anchorOffset===a.focusOffset}:function(a){return a.rangeCount?a.getRangeAt(a.rangeCount-1).collapsed:false};var B;s.isHostMethod(t,"getRangeAt")?B=function(a,b){try{return a.getRangeAt(b)}catch(c){return null}}:E&&(B=function(a){var c=m.getDocument(a.anchorNode),c=b.createRange(c);c.setStart(a.anchorNode,a.anchorOffset);c.setEnd(a.focusNode,a.focusOffset);if(c.collapsed!==this.isCollapsed){c.setStart(a.focusNode,
a.focusOffset);c.setEnd(a.anchorNode,a.anchorOffset)}return c});b.getSelection=function(a){var a=a||window,b=a._rangySelection,c=y(a),e=v?d(a):null;if(b){b.nativeSelection=c;b.docSelection=e;b.refresh(a)}else{b=new n(c,e,a);a._rangySelection=b}return b};b.getIframeSelection=function(a){return b.getSelection(m.getIframeWindow(a))};u=n.prototype;if(!D&&E&&s.areHostMethods(t,["removeAllRanges","addRange"])){u.removeAllRanges=function(){this.nativeSelection.removeAllRanges();f(this)};var L=function(a,
c){var d=x.getRangeDocument(c),d=b.createRange(d);d.collapseToPoint(c.endContainer,c.endOffset);a.nativeSelection.addRange(g(d));a.nativeSelection.extend(c.startContainer,c.startOffset);a.refresh()};u.addRange=N?function(a,c){if(l&&v&&this.docSelection.type=="Control")j(this,a);else if(c&&I)L(this,a);else{var d;if(J)d=this.rangeCount;else{this.removeAllRanges();d=0}this.nativeSelection.addRange(g(a));this.rangeCount=this.nativeSelection.rangeCount;if(this.rangeCount==d+1){if(b.config.checkSelectionRanges)(d=
B(this.nativeSelection,this.rangeCount-1))&&!x.rangesEqual(d,a)&&(a=new o(d));this._ranges[this.rangeCount-1]=a;e(this,a,H(this.nativeSelection));this.isCollapsed=A(this)}else this.refresh()}}:function(a,b){if(b&&I)L(this,a);else{this.nativeSelection.addRange(g(a));this.refresh()}};u.setRanges=function(a){if(l&&a.length>1)p(this,a);else{this.removeAllRanges();for(var b=0,c=a.length;b<c;++b)this.addRange(a[b])}}}else if(s.isHostMethod(t,"empty")&&s.isHostMethod(K,"select")&&l&&D)u.removeAllRanges=
function(){try{this.docSelection.empty();if(this.docSelection.type!="None"){var a;if(this.anchorNode)a=m.getDocument(this.anchorNode);else if(this.docSelection.type=="Control"){var b=this.docSelection.createRange();b.length&&(a=m.getDocument(b.item(0)).body.createTextRange())}if(a){a.body.createTextRange().select();this.docSelection.empty()}}}catch(c){}f(this)},u.addRange=function(a){if(this.docSelection.type=="Control")j(this,a);else{o.rangeToTextRange(a).select();this._ranges[0]=a;this.rangeCount=
1;this.isCollapsed=this._ranges[0].collapsed;e(this,a,false)}},u.setRanges=function(a){this.removeAllRanges();var b=a.length;b>1?p(this,a):b&&this.addRange(a[0])};else return c.fail("No means of selecting a Range or TextRange was found"),!1;u.getRangeAt=function(a){if(a<0||a>=this.rangeCount)throw new z("INDEX_SIZE_ERR");return this._ranges[a]};var G;if(D)G=function(a){var c;if(b.isSelectionValid(a.win))c=a.docSelection.createRange();else{c=m.getBody(a.win.document).createTextRange();c.collapse(true)}a.docSelection.type==
"Control"?k(a):c&&typeof c.text!="undefined"?h(a,c):f(a)};else if(s.isHostMethod(t,"getRangeAt")&&"number"==typeof t.rangeCount)G=function(a){if(l&&v&&a.docSelection.type=="Control")k(a);else{a._ranges.length=a.rangeCount=a.nativeSelection.rangeCount;if(a.rangeCount){for(var c=0,d=a.rangeCount;c<d;++c)a._ranges[c]=new b.WrappedRange(a.nativeSelection.getRangeAt(c));e(a,a._ranges[a.rangeCount-1],H(a.nativeSelection));a.isCollapsed=A(a)}else f(a)}};else if(E&&"boolean"==typeof t.isCollapsed&&"boolean"==
typeof K.collapsed&&b.features.implementsDomRange)G=function(a){var b;b=a.nativeSelection;if(b.anchorNode){b=B(b,0);a._ranges=[b];a.rangeCount=1;b=a.nativeSelection;a.anchorNode=b.anchorNode;a.anchorOffset=b.anchorOffset;a.focusNode=b.focusNode;a.focusOffset=b.focusOffset;a.isCollapsed=A(a)}else f(a)};else return c.fail("No means of obtaining a Range or TextRange from the user's selection was found"),!1;u.refresh=function(a){var b=a?this._ranges.slice(0):null;G(this);if(a){a=b.length;if(a!=this._ranges.length)return false;
for(;a--;)if(!x.rangesEqual(b[a],this._ranges[a]))return false;return true}};var P=function(a,b){var c=a.getAllRanges(),d=false;a.removeAllRanges();for(var e=0,h=c.length;e<h;++e)d||b!==c[e]?a.addRange(c[e]):d=true;a.rangeCount||f(a)};u.removeRange=l?function(a){if(this.docSelection.type=="Control"){for(var b=this.docSelection.createRange(),a=i(a),c=m.getDocument(b.item(0)),c=m.getBody(c).createControlRange(),d,e=false,h=0,j=b.length;h<j;++h){d=b.item(h);d!==a||e?c.add(b.item(h)):e=true}c.select();
k(this)}else P(this,a)}:function(a){P(this,a)};var H;!D&&E&&b.features.implementsDomRange?(H=function(a){var b=false;a.anchorNode&&(b=m.comparePoints(a.anchorNode,a.anchorOffset,a.focusNode,a.focusOffset)==1);return b},u.isBackwards=function(){return H(this)}):H=u.isBackwards=function(){return false};u.toString=function(){for(var a=[],b=0,c=this.rangeCount;b<c;++b)a[b]=""+this._ranges[b];return a.join("")};u.collapse=function(a,c){q(this,a);var d=b.createRange(m.getDocument(a));d.collapseToPoint(a,
c);this.removeAllRanges();this.addRange(d);this.isCollapsed=true};u.collapseToStart=function(){if(this.rangeCount){var a=this._ranges[0];this.collapse(a.startContainer,a.startOffset)}else throw new z("INVALID_STATE_ERR");};u.collapseToEnd=function(){if(this.rangeCount){var a=this._ranges[this.rangeCount-1];this.collapse(a.endContainer,a.endOffset)}else throw new z("INVALID_STATE_ERR");};u.selectAllChildren=function(a){q(this,a);var c=b.createRange(m.getDocument(a));c.selectNodeContents(a);this.removeAllRanges();
this.addRange(c)};u.deleteFromDocument=function(){if(l&&v&&this.docSelection.type=="Control"){for(var a=this.docSelection.createRange(),b;a.length;){b=a.item(0);a.remove(b);b.parentNode.removeChild(b)}this.refresh()}else if(this.rangeCount){a=this.getAllRanges();this.removeAllRanges();b=0;for(var c=a.length;b<c;++b)a[b].deleteContents();this.addRange(a[c-1])}};u.getAllRanges=function(){return this._ranges.slice(0)};u.setSingleRange=function(a){this.setRanges([a])};u.containsNode=function(a,b){for(var c=
0,d=this._ranges.length;c<d;++c)if(this._ranges[c].containsNode(a,b))return true;return false};u.toHtml=function(){var a="";if(this.rangeCount){for(var a=x.getRangeDocument(this._ranges[0]).createElement("div"),b=0,c=this._ranges.length;b<c;++b)a.appendChild(this._ranges[b].cloneContents());a=a.innerHTML}return a};u.getName=function(){return"WrappedSelection"};u.inspect=function(){return r(this)};u.detach=function(){this.win=this.anchorNode=this.focusNode=this.win._rangySelection=null};n.inspect=
r;b.Selection=n;b.selectionPrototype=u;b.addCreateMissingNativeApiListener(function(a){if(typeof a.getSelection=="undefined")a.getSelection=function(){return b.getSelection(this)};a=null})});var Base=function(){};
Base.extend=function(b,c){var a=Base.prototype.extend;Base._prototyping=!0;var d=new this;a.call(d,b);d.base=function(){};delete Base._prototyping;var e=d.constructor,f=d.constructor=function(){if(!Base._prototyping)if(this._constructing||this.constructor==f)this._constructing=!0,e.apply(this,arguments),delete this._constructing;else if(null!=arguments[0])return(arguments[0].extend||a).call(arguments[0],d)};f.ancestor=this;f.extend=this.extend;f.forEach=this.forEach;f.implement=this.implement;f.prototype=
d;f.toString=this.toString;f.valueOf=function(a){return"object"==a?f:e.valueOf()};a.call(f,c);"function"==typeof f.init&&f.init();return f};
Base.prototype={extend:function(b,c){if(1<arguments.length){var a=this[b];if(a&&"function"==typeof c&&(!a.valueOf||a.valueOf()!=c.valueOf())&&/\bbase\b/.test(c)){var d=c.valueOf(),c=function(){var b=this.base||Base.prototype.base;this.base=a;var c=d.apply(this,arguments);this.base=b;return c};c.valueOf=function(a){return"object"==a?c:d};c.toString=Base.toString}this[b]=c}else if(b){var e=Base.prototype.extend;!Base._prototyping&&"function"!=typeof this&&(e=this.extend||e);for(var f={toSource:null},
g=["constructor","toString","valueOf"],i=Base._prototyping?0:1;h=g[i++];)b[h]!=f[h]&&e.call(this,h,b[h]);for(var h in b)f[h]||e.call(this,h,b[h])}return this}};
Base=Base.extend({constructor:function(b){this.extend(b)}},{ancestor:Object,version:"1.1",forEach:function(b,c,a){for(var d in b)void 0===this.prototype[d]&&c.call(a,b[d],d,b)},implement:function(){for(var b=0;b<arguments.length;b++)if("function"==typeof arguments[b])arguments[b](this.prototype);else this.prototype.extend(arguments[b]);return this},toString:function(){return""+this.valueOf()}});
wysihtml5.browser=function(){var b=navigator.userAgent,c=document.createElement("div"),a=-1!==b.indexOf("MSIE")&&-1===b.indexOf("Opera"),d=-1!==b.indexOf("Gecko")&&-1===b.indexOf("KHTML"),e=-1!==b.indexOf("AppleWebKit/"),f=-1!==b.indexOf("Chrome/"),g=-1!==b.indexOf("Opera/");return{USER_AGENT:b,supported:function(){var a=this.USER_AGENT.toLowerCase(),b="contentEditable"in c,d=document.execCommand&&document.queryCommandSupported&&document.queryCommandState,e=document.querySelector&&document.querySelectorAll,
a=this.isIos()&&5>(/ipad|iphone|ipod/.test(a)&&a.match(/ os (\d+).+? like mac os x/)||[,0])[1]||-1!==a.indexOf("opera mobi")||-1!==a.indexOf("hpwos/");return b&&d&&e&&!a},isTouchDevice:function(){return this.supportsEvent("touchmove")},isIos:function(){var a=this.USER_AGENT.toLowerCase();return-1!==a.indexOf("webkit")&&-1!==a.indexOf("mobile")},supportsSandboxedIframes:function(){return a},throwsMixedContentWarningWhenIframeSrcIsEmpty:function(){return!("querySelector"in document)},displaysCaretInEmptyContentEditableCorrectly:function(){return!d},
hasCurrentStyleProperty:function(){return"currentStyle"in c},insertsLineBreaksOnReturn:function(){return d},supportsPlaceholderAttributeOn:function(a){return"placeholder"in a},supportsEvent:function(a){var b;if(!(b="on"+a in c))c.setAttribute("on"+a,"return;"),b="function"===typeof c["on"+a];return b},supportsEventsInIframeCorrectly:function(){return!g},firesOnDropOnlyWhenOnDragOverIsCancelled:function(){return e||d},supportsDataTransfer:function(){try{return e&&(window.Clipboard||window.DataTransfer).prototype.getData}catch(a){return!1}},
supportsHTML5Tags:function(a){a=a.createElement("div");a.innerHTML="<article>foo</article>";return"<article>foo</article>"===a.innerHTML.toLowerCase()},supportsCommand:function(){var b={formatBlock:a,insertUnorderedList:a||g||e,insertOrderedList:a||g||e},c={insertHTML:d};return function(a,d){if(!b[d]){try{return a.queryCommandSupported(d)}catch(e){}try{return a.queryCommandEnabled(d)}catch(f){return!!c[d]}}return!1}}(),doesAutoLinkingInContentEditable:function(){return a},canDisableAutoLinking:function(){return this.supportsCommand(document,
"AutoUrlDetect")},clearsContentEditableCorrectly:function(){return d||g||e},supportsGetAttributeCorrectly:function(){return"1"!=document.createElement("td").getAttribute("rowspan")},canSelectImagesInContentEditable:function(){return d||a||g},clearsListsInContentEditableCorrectly:function(){return d||a||e},autoScrollsToCaret:function(){return!e},autoClosesUnclosedTags:function(){var a=c.cloneNode(!1),b;a.innerHTML="<p><div></div>";a=a.innerHTML.toLowerCase();b="<p></p><div></div>"===a||"<p><div></div></p>"===
a;this.autoClosesUnclosedTags=function(){return b};return b},supportsNativeGetElementsByClassName:function(){return-1!==(""+document.getElementsByClassName).indexOf("[native code]")},supportsSelectionModify:function(){return"getSelection"in window&&"modify"in window.getSelection()},supportsClassList:function(){return"classList"in c},needsSpaceAfterLineBreak:function(){return g},supportsSpeechApiOn:function(a){return 11<=(b.match(/Chrome\/(\d+)/)||[,0])[1]&&("onwebkitspeechchange"in a||"speech"in a)},
crashesWhenDefineProperty:function(b){return a&&("XMLHttpRequest"===b||"XDomainRequest"===b)},doesAsyncFocus:function(){return a},hasProblemsSettingCaretAfterImg:function(){return a},hasUndoInContextMenu:function(){return d||f||g}}}();
wysihtml5.lang.array=function(b){return{contains:function(c){if(b.indexOf)return-1!==b.indexOf(c);for(var a=0,d=b.length;a<d;a++)if(b[a]===c)return!0;return!1},without:function(c){for(var c=wysihtml5.lang.array(c),a=[],d=0,e=b.length;d<e;d++)c.contains(b[d])||a.push(b[d]);return a},get:function(){for(var c=0,a=b.length,d=[];c<a;c++)d.push(b[c]);return d}}};
wysihtml5.lang.Dispatcher=Base.extend({observe:function(b,c){this.events=this.events||{};this.events[b]=this.events[b]||[];this.events[b].push(c);return this},on:function(){return this.observe.apply(this,wysihtml5.lang.array(arguments).get())},fire:function(b,c){this.events=this.events||{};for(var a=this.events[b]||[],d=0;d<a.length;d++)a[d].call(this,c);return this},stopObserving:function(b,c){this.events=this.events||{};var a=0,d,e;if(b){d=this.events[b]||[];for(e=[];a<d.length;a++)d[a]!==c&&c&&
e.push(d[a]);this.events[b]=e}else this.events={};return this}});wysihtml5.lang.object=function(b){return{merge:function(c){for(var a in c)b[a]=c[a];return this},get:function(){return b},clone:function(){var c={},a;for(a in b)c[a]=b[a];return c},isArray:function(){return"[object Array]"===Object.prototype.toString.call(b)}}};
(function(){var b=/^\s+/,c=/\s+$/;wysihtml5.lang.string=function(a){a=""+a;return{trim:function(){return a.replace(b,"").replace(c,"")},interpolate:function(b){for(var c in b)a=this.replace("#{"+c+"}").by(b[c]);return a},replace:function(b){return{by:function(c){return a.split(b).join(c)}}}}}})();
(function(b){function c(a){return a.replace(e,function(a,b){var c=(b.match(f)||[])[1]||"",d=i[c],b=b.replace(f,"");b.split(d).length>b.split(c).length&&(b+=c,c="");var e=d=b;b.length>g&&(e=e.substr(0,g)+"...");"www."===d.substr(0,4)&&(d="http://"+d);return'<a href="'+d+'">'+e+"</a>"+c})}function a(h){if(!d.contains(h.nodeName))if(h.nodeType===b.TEXT_NODE&&h.data.match(e)){var f=h.parentNode,j;j=f.ownerDocument;var g=j._wysihtml5_tempElement;g||(g=j._wysihtml5_tempElement=j.createElement("div"));j=
g;j.innerHTML="<span></span>"+c(h.data);for(j.removeChild(j.firstChild);j.firstChild;)f.insertBefore(j.firstChild,h);f.removeChild(h)}else{f=b.lang.array(h.childNodes).get();j=f.length;for(g=0;g<j;g++)a(f[g]);return h}}var d=b.lang.array("CODE PRE A SCRIPT HEAD TITLE STYLE".split(" ")),e=/((https?:\/\/|www\.)[^\s<]{3,})/gi,f=/([^\w\/\-](,?))$/i,g=100,i={")":"(","]":"[","}":"{"};b.dom.autoLink=function(b){var c;a:{c=b;for(var e;c.parentNode;){c=c.parentNode;e=c.nodeName;if(d.contains(e)){c=!0;break a}if("body"===
e)break}c=!1}if(c)return b;b===b.ownerDocument.documentElement&&(b=b.ownerDocument.body);return a(b)};b.dom.autoLink.URL_REG_EXP=e})(wysihtml5);
(function(b){var c=b.browser.supportsClassList(),a=b.dom;a.addClass=function(b,e){if(c)return b.classList.add(e);a.hasClass(b,e)||(b.className+=" "+e)};a.removeClass=function(a,b){if(c)return a.classList.remove(b);a.className=a.className.replace(RegExp("(^|\\s+)"+b+"(\\s+|$)")," ")};a.hasClass=function(a,b){if(c)return a.classList.contains(b);var f=a.className;return 0<f.length&&(f==b||RegExp("(^|\\s)"+b+"(\\s|$)").test(f))}})(wysihtml5);
wysihtml5.dom.contains=function(){var b=document.documentElement;if(b.contains)return function(b,a){a.nodeType!==wysihtml5.ELEMENT_NODE&&(a=a.parentNode);return b!==a&&b.contains(a)};if(b.compareDocumentPosition)return function(b,a){return!!(b.compareDocumentPosition(a)&16)}}();
wysihtml5.dom.convertToList=function(){function b(b,a){var d=b.createElement("li");a.appendChild(d);return d}return function(c,a){if("UL"===c.nodeName||"OL"===c.nodeName||"MENU"===c.nodeName)return c;var d=c.ownerDocument,e=d.createElement(a),f=c.querySelectorAll("br"),g=f.length,i,h,k,j,n;for(n=0;n<g;n++)for(i=f[n];(h=i.parentNode)&&h!==c&&h.lastChild===i;){if("block"===wysihtml5.dom.getStyle("display").from(h)){h.removeChild(i);break}wysihtml5.dom.insert(i).after(i.parentNode)}f=wysihtml5.lang.array(c.childNodes).get();
g=f.length;for(n=0;n<g;n++)j=j||b(d,e),i=f[n],h="block"===wysihtml5.dom.getStyle("display").from(i),k="BR"===i.nodeName,h?(j=j.firstChild?b(d,e):j,j.appendChild(i),j=null):k?j=j.firstChild?null:j:j.appendChild(i);c.parentNode.replaceChild(e,c);return e}}();wysihtml5.dom.copyAttributes=function(b){return{from:function(c){return{to:function(a){for(var d,e=0,f=b.length;e<f;e++)d=b[e],"undefined"!==typeof c[d]&&""!==c[d]&&(a[d]=c[d]);return{andTo:arguments.callee}}}}}};
(function(b){var c=["-webkit-box-sizing","-moz-box-sizing","-ms-box-sizing","box-sizing"],a=function(a){var e;a:for(var f=0,g=c.length;f<g;f++)if("border-box"===b.getStyle(c[f]).from(a)){e=c[f];break a}return e?parseInt(b.getStyle("width").from(a),10)<a.offsetWidth:!1};b.copyStyles=function(d){return{from:function(e){a(e)&&(d=wysihtml5.lang.array(d).without(c));for(var f="",g=d.length,i=0,h;i<g;i++)h=d[i],f+=h+":"+b.getStyle(h).from(e)+";";return{to:function(a){b.setStyles(f).on(a);return{andTo:arguments.callee}}}}}}})(wysihtml5.dom);
(function(b){b.dom.delegate=function(c,a,d,e){return b.dom.observe(c,d,function(d){for(var g=d.target,i=b.lang.array(c.querySelectorAll(a));g&&g!==c;){if(i.contains(g)){e.call(g,d);break}g=g.parentNode}})}})(wysihtml5);
wysihtml5.dom.getAsDom=function(){var b="abbr article aside audio bdi canvas command datalist details figcaption figure footer header hgroup keygen mark meter nav output progress rp rt ruby svg section source summary time track video wbr".split(" ");return function(c,a){var a=a||document,d;if("object"===typeof c&&c.nodeType)d=a.createElement("div"),d.appendChild(c);else if(wysihtml5.browser.supportsHTML5Tags(a))d=a.createElement("div"),d.innerHTML=c;else{d=a;if(!d._wysihtml5_supportsHTML5Tags){for(var e=
0,f=b.length;e<f;e++)d.createElement(b[e]);d._wysihtml5_supportsHTML5Tags=!0}d=a;e=d.createElement("div");e.style.display="none";d.body.appendChild(e);try{e.innerHTML=c}catch(g){}d.body.removeChild(e);d=e}return d}}();
wysihtml5.dom.getParentElement=function(){function b(b,a){return!a||!a.length?!0:"string"===typeof a?b===a:wysihtml5.lang.array(a).contains(b)}return function(c,a,d){d=d||50;if(a.className||a.classRegExp){a:{for(var e=a.nodeName,f=a.className,a=a.classRegExp;d--&&c&&"BODY"!==c.nodeName;){var g;if(g=c.nodeType===wysihtml5.ELEMENT_NODE)if(g=b(c.nodeName,e)){g=f;var i=(c.className||"").match(a)||[];g=!g?!!i.length:i[i.length-1]===g}if(g)break a;c=c.parentNode}c=null}return c}a:{e=a.nodeName;for(f=d;f--&&
c&&"BODY"!==c.nodeName;){if(b(c.nodeName,e))break a;c=c.parentNode}c=null}return c}}();
wysihtml5.dom.getStyle=function(){function b(b){return b.replace(a,function(a){return a.charAt(1).toUpperCase()})}var c={"float":"styleFloat"in document.createElement("div").style?"styleFloat":"cssFloat"},a=/\-[a-z]/g;return function(a){return{from:function(e){if(e.nodeType===wysihtml5.ELEMENT_NODE){var f=e.ownerDocument,g=c[a]||b(a),i=e.style,h=e.currentStyle,k=i[g];if(k)return k;if(h)try{return h[g]}catch(j){}var g=f.defaultView||f.parentWindow,f=("height"===a||"width"===a)&&"TEXTAREA"===e.nodeName,
n;if(g.getComputedStyle)return f&&(n=i.overflow,i.overflow="hidden"),e=g.getComputedStyle(e,null).getPropertyValue(a),f&&(i.overflow=n||""),e}}}}}();wysihtml5.dom.hasElementWithTagName=function(){var b={},c=1;return function(a,d){var e=(a._wysihtml5_identifier||(a._wysihtml5_identifier=c++))+":"+d,f=b[e];f||(f=b[e]=a.getElementsByTagName(d));return 0<f.length}}();
(function(b){var c={},a=1;b.dom.hasElementWithClassName=function(d,e){if(!b.browser.supportsNativeGetElementsByClassName())return!!d.querySelector("."+e);var f=(d._wysihtml5_identifier||(d._wysihtml5_identifier=a++))+":"+e,g=c[f];g||(g=c[f]=d.getElementsByClassName(e));return 0<g.length}})(wysihtml5);wysihtml5.dom.insert=function(b){return{after:function(c){c.parentNode.insertBefore(b,c.nextSibling)},before:function(c){c.parentNode.insertBefore(b,c)},into:function(c){c.appendChild(b)}}};
wysihtml5.dom.insertCSS=function(b){b=b.join("\n");return{into:function(c){var a=c.head||c.getElementsByTagName("head")[0],d=c.createElement("style");d.type="text/css";d.styleSheet?d.styleSheet.cssText=b:d.appendChild(c.createTextNode(b));a&&a.appendChild(d)}}};
wysihtml5.dom.observe=function(b,c,a){for(var c="string"===typeof c?[c]:c,d,e,f=0,g=c.length;f<g;f++)e=c[f],b.addEventListener?b.addEventListener(e,a,!1):(d=function(c){"target"in c||(c.target=c.srcElement);c.preventDefault=c.preventDefault||function(){this.returnValue=false};c.stopPropagation=c.stopPropagation||function(){this.cancelBubble=true};a.call(b,c)},b.attachEvent("on"+e,d));return{stop:function(){for(var e,h=0,f=c.length;h<f;h++)e=c[h],b.removeEventListener?b.removeEventListener(e,a,!1):
b.detachEvent("on"+e,d)}}};
wysihtml5.dom.parse=function(){function b(c,e){var h=c.childNodes,f=h.length,g;g=a[c.nodeType];var k=0;g=g&&g(c);if(!g)return null;for(k=0;k<f;k++)(newChild=b(h[k],e))&&g.appendChild(newChild);return e&&1>=g.childNodes.length&&g.nodeName.toLowerCase()===d&&!g.attributes.length?g.firstChild:g}function c(a,b){var b=b.toLowerCase(),c;if(c="IMG"==a.nodeName)if(c="src"==b){var d;try{d=a.complete&&!a.mozMatchesSelector(":-moz-broken")}catch(e){a.complete&&"complete"===a.readyState&&(d=!0)}c=!0===d}return c?
a.src:i&&"outerHTML"in a?-1!=a.outerHTML.toLowerCase().indexOf(" "+b+"=")?a.getAttribute(b):null:a.getAttribute(b)}var a={1:function(a){var b,f,i=g.tags;f=a.nodeName.toLowerCase();b=a.scopeName;if(a._wysihtml5)return null;a._wysihtml5=1;if("wysihtml5-temp"===a.className)return null;b&&"HTML"!=b&&(f=b+":"+f);"outerHTML"in a&&!wysihtml5.browser.autoClosesUnclosedTags()&&("P"===a.nodeName&&"</p>"!==a.outerHTML.slice(-4).toLowerCase())&&(f="div");if(f in i){b=i[f];if(!b||b.remove)return null;b="string"===
typeof b?{rename_tag:b}:b}else if(a.firstChild)b={rename_tag:d};else return null;f=a.ownerDocument.createElement(b.rename_tag||f);var i={},r=b.set_class,m=b.add_class,s=b.set_attributes,x=b.check_attributes,o=g.classes,z=0,w=[];b=[];var y=[],A=[],t;s&&(i=wysihtml5.lang.object(s).clone());if(x)for(t in x)if(s=h[x[t]])s=s(c(a,t)),"string"===typeof s&&(i[t]=s);r&&w.push(r);if(m)for(t in m)if(s=k[m[t]])r=s(c(a,t)),"string"===typeof r&&w.push(r);o["_wysihtml5-temp-placeholder"]=1;(A=a.getAttribute("class"))&&
(w=w.concat(A.split(e)));for(m=w.length;z<m;z++)a=w[z],o[a]&&b.push(a);for(o=b.length;o--;)a=b[o],wysihtml5.lang.array(y).contains(a)||y.unshift(a);y.length&&(i["class"]=y.join(" "));for(t in i)try{f.setAttribute(t,i[t])}catch(v){}i.src&&("undefined"!==typeof i.width&&f.setAttribute("width",i.width),"undefined"!==typeof i.height&&f.setAttribute("height",i.height));return f},3:function(a){return a.ownerDocument.createTextNode(a.data)}},d="span",e=/\s+/,f={tags:{},classes:{}},g={},i=!wysihtml5.browser.supportsGetAttributeCorrectly(),
h={url:function(){var a=/^https?:\/\//i;return function(b){return!b||!b.match(a)?null:b.replace(a,function(a){return a.toLowerCase()})}}(),alt:function(){var a=/[^ a-z0-9_\-]/gi;return function(b){return!b?"":b.replace(a,"")}}(),numbers:function(){var a=/\D/g;return function(b){return(b=(b||"").replace(a,""))||null}}()},k={align_img:function(){var a={left:"wysiwyg-float-left",right:"wysiwyg-float-right"};return function(b){return a[(""+b).toLowerCase()]}}(),align_text:function(){var a={left:"wysiwyg-text-align-left",
right:"wysiwyg-text-align-right",center:"wysiwyg-text-align-center",justify:"wysiwyg-text-align-justify"};return function(b){return a[(""+b).toLowerCase()]}}(),clear_br:function(){var a={left:"wysiwyg-clear-left",right:"wysiwyg-clear-right",both:"wysiwyg-clear-both",all:"wysiwyg-clear-both"};return function(b){return a[(""+b).toLowerCase()]}}(),size_font:function(){var a={1:"wysiwyg-font-size-xx-small",2:"wysiwyg-font-size-small",3:"wysiwyg-font-size-medium",4:"wysiwyg-font-size-large",5:"wysiwyg-font-size-x-large",
6:"wysiwyg-font-size-xx-large",7:"wysiwyg-font-size-xx-large","-":"wysiwyg-font-size-smaller","+":"wysiwyg-font-size-larger"};return function(b){return a[(""+b).charAt(0)]}}()};return function(a,c,d,e){wysihtml5.lang.object(g).merge(f).merge(c).get();for(var d=d||a.ownerDocument||document,c=d.createDocumentFragment(),h="string"===typeof a,a=h?wysihtml5.dom.getAsDom(a,d):a;a.firstChild;)d=a.firstChild,a.removeChild(d),(d=b(d,e))&&c.appendChild(d);a.innerHTML="";a.appendChild(c);return h?wysihtml5.quirks.getCorrectInnerHTML(a):
a}}();wysihtml5.dom.removeEmptyTextNodes=function(b){for(var c=wysihtml5.lang.array(b.childNodes).get(),a=c.length,d=0;d<a;d++)b=c[d],b.nodeType===wysihtml5.TEXT_NODE&&""===b.data&&b.parentNode.removeChild(b)};wysihtml5.dom.renameElement=function(b,c){for(var a=b.ownerDocument.createElement(c),d;d=b.firstChild;)a.appendChild(d);wysihtml5.dom.copyAttributes(["align","className"]).from(b).to(a);b.parentNode.replaceChild(a,b);return a};
wysihtml5.dom.replaceWithChildNodes=function(b){if(b.parentNode)if(b.firstChild){for(var c=b.ownerDocument.createDocumentFragment();b.firstChild;)c.appendChild(b.firstChild);b.parentNode.replaceChild(c,b)}else b.parentNode.removeChild(b)};
(function(b){function c(a){var b=a.ownerDocument.createElement("br");a.appendChild(b)}b.resolveList=function(a){if(!("MENU"!==a.nodeName&&"UL"!==a.nodeName&&"OL"!==a.nodeName)){var d=a.ownerDocument.createDocumentFragment(),e=a.previousElementSibling||a.previousSibling,f,g,i;for(e&&"block"!==b.getStyle("display").from(e)&&c(d);i=a.firstChild;){for(f=i.lastChild;e=i.firstChild;)g=(g=e===f)&&"block"!==b.getStyle("display").from(e)&&"BR"!==e.nodeName,d.appendChild(e),g&&c(d);i.parentNode.removeChild(i)}a.parentNode.replaceChild(d,
a)}}})(wysihtml5.dom);
(function(b){var c=document,a="parent top opener frameElement frames localStorage globalStorage sessionStorage indexedDB".split(" "),d="open close openDialog showModalDialog alert confirm prompt openDatabase postMessage XMLHttpRequest XDomainRequest".split(" "),e=["referrer","write","open","close"];b.dom.Sandbox=Base.extend({constructor:function(a,c){this.callback=a||b.EMPTY_FUNCTION;this.config=b.lang.object({}).merge(c).get();this.iframe=this._createIframe()},insertInto:function(a){"string"===typeof a&&
(a=c.getElementById(a));a.appendChild(this.iframe)},getIframe:function(){return this.iframe},getWindow:function(){this._readyError()},getDocument:function(){this._readyError()},destroy:function(){var a=this.getIframe();a.parentNode.removeChild(a)},_readyError:function(){throw Error("wysihtml5.Sandbox: Sandbox iframe isn't loaded yet");},_createIframe:function(){var a=this,d=c.createElement("iframe");d.className="wysihtml5-sandbox";b.dom.setAttributes({security:"restricted",allowtransparency:"true",
frameborder:0,width:0,height:0,marginwidth:0,marginheight:0}).on(d);b.browser.throwsMixedContentWarningWhenIframeSrcIsEmpty()&&(d.src="javascript:'<html></html>'");d.onload=function(){d.onreadystatechange=d.onload=null;a._onLoadIframe(d)};d.onreadystatechange=function(){if(/loaded|complete/.test(d.readyState)){d.onreadystatechange=d.onload=null;a._onLoadIframe(d)}};return d},_onLoadIframe:function(f){if(b.dom.contains(c.documentElement,f)){var g=this,i=f.contentWindow,h=f.contentWindow.document,k=
this._getHtml({charset:c.characterSet||c.charset||"utf-8",stylesheets:this.config.stylesheets});h.open("text/html","replace");h.write(k);h.close();this.getWindow=function(){return f.contentWindow};this.getDocument=function(){return f.contentWindow.document};i.onerror=function(a,b,c){throw Error("wysihtml5.Sandbox: "+a,b,c);};if(!b.browser.supportsSandboxedIframes()){var j,k=0;for(j=a.length;k<j;k++)this._unset(i,a[k]);k=0;for(j=d.length;k<j;k++)this._unset(i,d[k],b.EMPTY_FUNCTION);k=0;for(j=e.length;k<
j;k++)this._unset(h,e[k]);this._unset(h,"cookie","",!0)}this.loaded=!0;setTimeout(function(){g.callback(g)},0)}},_getHtml:function(a){var c=a.stylesheets,d="",e=0,k;if(c="string"===typeof c?[c]:c)for(k=c.length;e<k;e++)d+='<link rel="stylesheet" href="'+c[e]+'">';a.stylesheets=d;return b.lang.string('<!DOCTYPE html><html><head><meta charset="#{charset}">#{stylesheets}</head><body></body></html>').interpolate(a)},_unset:function(a,c,d,e){try{a[c]=d}catch(k){}try{a.__defineGetter__(c,function(){return d})}catch(j){}if(e)try{a.__defineSetter__(c,
function(){})}catch(n){}if(!b.browser.crashesWhenDefineProperty(c))try{var p={get:function(){return d}};e&&(p.set=function(){});Object.defineProperty(a,c,p)}catch(q){}}})})(wysihtml5);(function(){var b={className:"class"};wysihtml5.dom.setAttributes=function(c){return{on:function(a){for(var d in c)a.setAttribute(b[d]||d,c[d])}}}})();
wysihtml5.dom.setStyles=function(b){return{on:function(c){c=c.style;if("string"===typeof b)c.cssText+=";"+b;else for(var a in b)"float"===a?(c.cssFloat=b[a],c.styleFloat=b[a]):c[a]=b[a]}}};
(function(b){b.simulatePlaceholder=function(c,a,d){var e=function(){a.hasPlaceholderSet()&&a.clear();b.removeClass(a.element,"placeholder")},f=function(){a.isEmpty()&&(a.setValue(d),b.addClass(a.element,"placeholder"))};c.observe("set_placeholder",f).observe("unset_placeholder",e).observe("focus:composer",e).observe("paste:composer",e).observe("blur:composer",f);f()}})(wysihtml5.dom);
(function(b){var c=document.documentElement;"textContent"in c?(b.setTextContent=function(a,b){a.textContent=b},b.getTextContent=function(a){return a.textContent}):"innerText"in c?(b.setTextContent=function(a,b){a.innerText=b},b.getTextContent=function(a){return a.innerText}):(b.setTextContent=function(a,b){a.nodeValue=b},b.getTextContent=function(a){return a.nodeValue})})(wysihtml5.dom);
wysihtml5.quirks.cleanPastedHTML=function(){var b={"a u":wysihtml5.dom.replaceWithChildNodes};return function(c,a,d){var a=a||b,d=d||c.ownerDocument||document,e="string"===typeof c,f,g,i,h=0,c=e?wysihtml5.dom.getAsDom(c,d):c;for(i in a){f=c.querySelectorAll(i);d=a[i];for(g=f.length;h<g;h++)d(f[h])}return e?c.innerHTML:c}}();
(function(b){var c=b.dom;b.quirks.ensureProperClearing=function(){var a=function(){var a=this;setTimeout(function(){var b=a.innerHTML.toLowerCase();if("<p>&nbsp;</p>"==b||"<p>&nbsp;</p><p>&nbsp;</p>"==b)a.innerHTML=""},0)};return function(b){c.observe(b.element,["cut","keydown"],a)}}();b.quirks.ensureProperClearingOfLists=function(){var a=["OL","UL","MENU"];return function(d){c.observe(d.element,"keydown",function(e){if(e.keyCode===b.BACKSPACE_KEY){var f=d.selection.getSelectedNode(),e=d.element;
e.firstChild&&b.lang.array(a).contains(e.firstChild.nodeName)&&(f=c.getParentElement(f,{nodeName:a}))&&f==e.firstChild&&1>=f.childNodes.length&&(f.firstChild?""===f.firstChild.innerHTML:1)&&f.parentNode.removeChild(f)}})}}()})(wysihtml5);
(function(b){b.quirks.getCorrectInnerHTML=function(c){var a=c.innerHTML;if(-1===a.indexOf("%7E"))return a;var c=c.querySelectorAll("[href*='~'], [src*='~']"),d,e,f,g;g=0;for(f=c.length;g<f;g++)d=c[g].href||c[g].src,e=b.lang.string(d).replace("~").by("%7E"),a=b.lang.string(a).replace(e).by(d);return a}})(wysihtml5);
(function(b){var c=b.dom,a="LI P H1 H2 H3 H4 H5 H6".split(" "),d=["UL","OL","MENU"];b.quirks.insertLineBreakOnReturn=function(e){function f(a){if(a=c.getParentElement(a,{nodeName:["P","DIV"]},2)){var d=document.createTextNode(b.INVISIBLE_SPACE);c.insert(d).before(a);c.replaceWithChildNodes(a);e.selection.selectNode(d)}}c.observe(e.element.ownerDocument,"keydown",function(g){var i=g.keyCode;if(!(g.shiftKey||i!==b.ENTER_KEY&&i!==b.BACKSPACE_KEY)){var h=e.selection.getSelectedNode();(h=c.getParentElement(h,
{nodeName:a},4))?"LI"===h.nodeName&&(i===b.ENTER_KEY||i===b.BACKSPACE_KEY)?setTimeout(function(){var a=e.selection.getSelectedNode(),b;a&&((b=c.getParentElement(a,{nodeName:d},2))||f(a))},0):h.nodeName.match(/H[1-6]/)&&i===b.ENTER_KEY&&setTimeout(function(){f(e.selection.getSelectedNode())},0):i===b.ENTER_KEY&&!b.browser.insertsLineBreaksOnReturn()&&(e.commands.exec("insertLineBreak"),g.preventDefault())}})}})(wysihtml5);
(function(b){b.quirks.redraw=function(c){b.dom.addClass(c,"wysihtml5-quirks-redraw");b.dom.removeClass(c,"wysihtml5-quirks-redraw");try{var a=c.ownerDocument;a.execCommand("italic",!1,null);a.execCommand("italic",!1,null)}catch(d){}}})(wysihtml5);
(function(b){var c=b.dom;b.Selection=Base.extend({constructor:function(a){window.rangy.init();this.editor=a;this.composer=a.composer;this.doc=this.composer.doc},getBookmark:function(){var a=this.getRange();return a&&a.cloneRange()},setBookmark:function(a){a&&this.setSelection(a)},setBefore:function(a){var b=rangy.createRange(this.doc);b.setStartBefore(a);b.setEndBefore(a);return this.setSelection(b)},setAfter:function(a){var b=rangy.createRange(this.doc);b.setStartAfter(a);b.setEndAfter(a);return this.setSelection(b)},
selectNode:function(a){var d=rangy.createRange(this.doc),e=a.nodeType===b.ELEMENT_NODE,f="canHaveHTML"in a?a.canHaveHTML:"IMG"!==a.nodeName,g=e?a.innerHTML:a.data,g=""===g||g===b.INVISIBLE_SPACE,i=c.getStyle("display").from(a),i="block"===i||"list-item"===i;if(g&&e&&f)try{a.innerHTML=b.INVISIBLE_SPACE}catch(h){}f?d.selectNodeContents(a):d.selectNode(a);f&&g&&e?d.collapse(i):f&&g&&(d.setStartAfter(a),d.setEndAfter(a));this.setSelection(d)},getSelectedNode:function(a){if(a&&this.doc.selection&&"Control"===
this.doc.selection.type&&(a=this.doc.selection.createRange())&&a.length)return a.item(0);a=this.getSelection(this.doc);return a.focusNode===a.anchorNode?a.focusNode:(a=this.getRange(this.doc))?a.commonAncestorContainer:this.doc.body},executeAndRestore:function(a,c){var e=this.doc.body,f=c&&e.scrollTop,g=c&&e.scrollLeft,i='<span class="_wysihtml5-temp-placeholder">'+b.INVISIBLE_SPACE+"</span>",h=this.getRange(this.doc);if(h){i=h.createContextualFragment(i);h.insertNode(i);try{a(h.startContainer,h.endContainer)}catch(k){setTimeout(function(){throw k;
},0)}(caretPlaceholder=this.doc.querySelector("._wysihtml5-temp-placeholder"))?(h=rangy.createRange(this.doc),h.selectNode(caretPlaceholder),h.deleteContents(),this.setSelection(h)):e.focus();c&&(e.scrollTop=f,e.scrollLeft=g);try{caretPlaceholder.parentNode.removeChild(caretPlaceholder)}catch(j){}}else a(e,e)},executeAndRestoreSimple:function(a){var b,c,f=this.getRange(),g=this.doc.body,i;if(f){b=f.getNodes([3]);g=b[0]||f.startContainer;i=b[b.length-1]||f.endContainer;b=g===f.startContainer?f.startOffset:
0;c=i===f.endContainer?f.endOffset:i.length;try{a(f.startContainer,f.endContainer)}catch(h){setTimeout(function(){throw h;},0)}a=rangy.createRange(this.doc);try{a.setStart(g,b)}catch(k){}try{a.setEnd(i,c)}catch(j){}try{this.setSelection(a)}catch(n){}}else a(g,g)},insertHTML:function(a){var a=rangy.createRange(this.doc).createContextualFragment(a),b=a.lastChild;this.insertNode(a);b&&this.setAfter(b)},insertNode:function(a){var b=this.getRange();b&&b.insertNode(a)},surround:function(a){var b=this.getRange();
if(b)try{b.surroundContents(a),this.selectNode(a)}catch(c){a.appendChild(b.extractContents()),b.insertNode(a)}},scrollIntoView:function(){var a=this.doc,c=a.documentElement.scrollHeight>a.documentElement.offsetHeight,e;if(!(e=a._wysihtml5ScrollIntoViewElement))e=a.createElement("span"),e.innerHTML=b.INVISIBLE_SPACE;e=a._wysihtml5ScrollIntoViewElement=e;if(c){this.insertNode(e);var c=e,f=0;if(c.parentNode){do f+=c.offsetTop||0,c=c.offsetParent;while(c)}c=f;e.parentNode.removeChild(e);c>a.body.scrollTop&&
(a.body.scrollTop=c)}},selectLine:function(){b.browser.supportsSelectionModify()?this._selectLine_W3C():this.doc.selection&&this._selectLine_MSIE()},_selectLine_W3C:function(){var a=this.doc.defaultView.getSelection();a.modify("extend","left","lineboundary");a.modify("extend","right","lineboundary")},_selectLine_MSIE:function(){var a=this.doc.selection.createRange(),b=a.boundingTop,c=this.doc.body.scrollWidth,f;if(a.moveToPoint){0===b&&(f=this.doc.createElement("span"),this.insertNode(f),b=f.offsetTop,
f.parentNode.removeChild(f));b+=1;for(f=-10;f<c;f+=2)try{a.moveToPoint(f,b);break}catch(g){}for(f=this.doc.selection.createRange();0<=c;c--)try{f.moveToPoint(c,b);break}catch(i){}a.setEndPoint("EndToEnd",f);a.select()}},getText:function(){var a=this.getSelection();return a?a.toString():""},getNodes:function(a,b){var c=this.getRange();return c?c.getNodes([a],b):[]},getRange:function(){var a=this.getSelection();return a&&a.rangeCount&&a.getRangeAt(0)},getSelection:function(){return rangy.getSelection(this.doc.defaultView||
this.doc.parentWindow)},setSelection:function(a){return rangy.getSelection(this.doc.defaultView||this.doc.parentWindow).setSingleRange(a)}})})(wysihtml5);
(function(b,c){function a(a,b){return c.dom.isCharacterDataNode(a)?0==b?!!a.previousSibling:b==a.length?!!a.nextSibling:!0:0<b&&b<a.childNodes.length}function d(a,b,e){var f;c.dom.isCharacterDataNode(b)&&(0==e?(e=c.dom.getNodeIndex(b),b=b.parentNode):e==b.length?(e=c.dom.getNodeIndex(b)+1,b=b.parentNode):f=c.dom.splitDataNode(b,e));if(!f){f=b.cloneNode(!1);f.id&&f.removeAttribute("id");for(var g;g=b.childNodes[e];)f.appendChild(g);c.dom.insertAfter(f,b)}return b==a?f:d(a,f.parentNode,c.dom.getNodeIndex(f))}
function e(a){this.firstTextNode=(this.isElementMerge=a.nodeType==b.ELEMENT_NODE)?a.lastChild:a;this.textNodes=[this.firstTextNode]}function f(a,b,c,d){this.tagNames=a||[g];this.cssClass=b||"";this.similarClassRegExp=c;this.normalize=d;this.applyToAnyTagName=!1}var g="span",i=/\s+/g;e.prototype={doMerge:function(){for(var a=[],b,c,d=0,e=this.textNodes.length;d<e;++d)b=this.textNodes[d],c=b.parentNode,a[d]=b.data,d&&(c.removeChild(b),c.hasChildNodes()||c.parentNode.removeChild(c));return this.firstTextNode.data=
a=a.join("")},getLength:function(){for(var a=this.textNodes.length,b=0;a--;)b+=this.textNodes[a].length;return b},toString:function(){for(var a=[],b=0,c=this.textNodes.length;b<c;++b)a[b]="'"+this.textNodes[b].data+"'";return"[Merge("+a.join(",")+")]"}};f.prototype={getAncestorWithClass:function(a){for(var d;a;){if(this.cssClass)if(d=this.cssClass,a.className){var e=a.className.match(this.similarClassRegExp)||[];d=e[e.length-1]===d}else d=!1;else d=!0;if(a.nodeType==b.ELEMENT_NODE&&c.dom.arrayContains(this.tagNames,
a.tagName.toLowerCase())&&d)return a;a=a.parentNode}return!1},postApply:function(a,b){for(var c=a[0],d=a[a.length-1],f=[],g,i=c,m=d,s=0,x=d.length,o,z,w=0,y=a.length;w<y;++w)if(o=a[w],z=this.getAdjacentMergeableTextNode(o.parentNode,!1)){if(g||(g=new e(z),f.push(g)),g.textNodes.push(o),o===c&&(i=g.firstTextNode,s=i.length),o===d)m=g.firstTextNode,x=g.getLength()}else g=null;if(c=this.getAdjacentMergeableTextNode(d.parentNode,!0))g||(g=new e(d),f.push(g)),g.textNodes.push(c);if(f.length){w=0;for(y=
f.length;w<y;++w)f[w].doMerge();b.setStart(i,s);b.setEnd(m,x)}},getAdjacentMergeableTextNode:function(a,c){var d=a.nodeType==b.TEXT_NODE,e=d?a.parentNode:a,f=c?"nextSibling":"previousSibling";if(d){if((d=a[f])&&d.nodeType==b.TEXT_NODE)return d}else if((d=e[f])&&this.areElementsMergeable(a,d))return d[c?"firstChild":"lastChild"];return null},areElementsMergeable:function(a,b){var d;if(d=c.dom.arrayContains(this.tagNames,(a.tagName||"").toLowerCase()))if(d=c.dom.arrayContains(this.tagNames,(b.tagName||
"").toLowerCase()))if(d=a.className.replace(i," ")==b.className.replace(i," "))a:if(a.attributes.length!=b.attributes.length)d=!1;else{d=0;for(var e=a.attributes.length,f,g;d<e;++d)if(f=a.attributes[d],g=f.name,"class"!=g&&(g=b.attributes.getNamedItem(g),f.specified!=g.specified||f.specified&&f.nodeValue!==g.nodeValue)){d=!1;break a}d=!0}return d},createContainer:function(a){a=a.createElement(this.tagNames[0]);this.cssClass&&(a.className=this.cssClass);return a},applyToTextNode:function(a){var b=
a.parentNode;1==b.childNodes.length&&c.dom.arrayContains(this.tagNames,b.tagName.toLowerCase())?this.cssClass&&(a=this.cssClass,b.className?(b.className&&(b.className=b.className.replace(this.similarClassRegExp,"")),b.className+=" "+a):b.className=a):(b=this.createContainer(c.dom.getDocument(a)),a.parentNode.insertBefore(b,a),b.appendChild(a))},isRemovable:function(a){return c.dom.arrayContains(this.tagNames,a.tagName.toLowerCase())&&b.lang.string(a.className).trim()==this.cssClass},undoToTextNode:function(b,
c,e){c.containsNode(e)||(b=c.cloneRange(),b.selectNode(e),b.isPointInRange(c.endContainer,c.endOffset)&&a(c.endContainer,c.endOffset)&&(d(e,c.endContainer,c.endOffset),c.setEndAfter(e)),b.isPointInRange(c.startContainer,c.startOffset)&&a(c.startContainer,c.startOffset)&&(e=d(e,c.startContainer,c.startOffset)));this.similarClassRegExp&&e.className&&(e.className=e.className.replace(this.similarClassRegExp,""));if(this.isRemovable(e)){c=e;for(e=c.parentNode;c.firstChild;)e.insertBefore(c.firstChild,
c);e.removeChild(c)}},applyToRange:function(a){var c=a.getNodes([b.TEXT_NODE]);if(!c.length)try{var d=this.createContainer(a.endContainer.ownerDocument);a.surroundContents(d);this.selectNode(a,d);return}catch(e){}a.splitBoundaries();c=a.getNodes([b.TEXT_NODE]);if(c.length){for(var f=0,g=c.length;f<g;++f)d=c[f],this.getAncestorWithClass(d)||this.applyToTextNode(d);a.setStart(c[0],0);d=c[c.length-1];a.setEnd(d,d.length);this.normalize&&this.postApply(c,a)}},undoToRange:function(a){var c=a.getNodes([b.TEXT_NODE]),
d,e;c.length?(a.splitBoundaries(),c=a.getNodes([b.TEXT_NODE])):(c=a.endContainer.ownerDocument.createTextNode(b.INVISIBLE_SPACE),a.insertNode(c),a.selectNode(c),c=[c]);for(var f=0,g=c.length;f<g;++f)d=c[f],(e=this.getAncestorWithClass(d))&&this.undoToTextNode(d,a,e);1==g?this.selectNode(a,c[0]):(a.setStart(c[0],0),d=c[c.length-1],a.setEnd(d,d.length),this.normalize&&this.postApply(c,a))},selectNode:function(a,c){var d=c.nodeType===b.ELEMENT_NODE,e="canHaveHTML"in c?c.canHaveHTML:!0,f=d?c.innerHTML:
c.data;if((f=""===f||f===b.INVISIBLE_SPACE)&&d&&e)try{c.innerHTML=b.INVISIBLE_SPACE}catch(g){}a.selectNodeContents(c);f&&d?a.collapse(!1):f&&(a.setStartAfter(c),a.setEndAfter(c))},getTextSelectedByRange:function(a,b){var c=b.cloneRange();c.selectNodeContents(a);var d=c.intersection(b),d=d?d.toString():"";c.detach();return d},isAppliedToRange:function(a){var c=[],d,e=a.getNodes([b.TEXT_NODE]);if(!e.length)return(d=this.getAncestorWithClass(a.startContainer))?[d]:!1;for(var f=0,g=e.length,i;f<g;++f){i=
this.getTextSelectedByRange(e[f],a);d=this.getAncestorWithClass(e[f]);if(""!=i&&!d)return!1;c.push(d)}return c},toggleRange:function(a){this.isAppliedToRange(a)?this.undoToRange(a):this.applyToRange(a)}};b.selection.HTMLApplier=f})(wysihtml5,rangy);
wysihtml5.Commands=Base.extend({constructor:function(b){this.editor=b;this.composer=b.composer;this.doc=this.composer.doc},support:function(b){return wysihtml5.browser.supportsCommand(this.doc,b)},exec:function(b,c){var a=wysihtml5.commands[b],d=wysihtml5.lang.array(arguments).get(),e=a&&a.exec,f=null;this.editor.fire("beforecommand:composer");if(e)d.unshift(this.composer),f=e.apply(a,d);else try{f=this.doc.execCommand(b,!1,c)}catch(g){}this.editor.fire("aftercommand:composer");return f},state:function(b,
c){var a=wysihtml5.commands[b],d=wysihtml5.lang.array(arguments).get(),e=a&&a.state;if(e)return d.unshift(this.composer),e.apply(a,d);try{return this.doc.queryCommandState(b)}catch(f){return!1}},value:function(b){var c=wysihtml5.commands[b],a=c&&c.value;if(a)return a.call(c,this.composer,b);try{return this.doc.queryCommandValue(b)}catch(d){return null}}});
(function(b){b.commands.bold={exec:function(c,a){return b.commands.formatInline.exec(c,a,"b")},state:function(c,a){return b.commands.formatInline.state(c,a,"b")},value:function(){}}})(wysihtml5);
(function(b){function c(c,g){var i=c.doc,h="_wysihtml5-temp-"+ +new Date,k=0,j,n,p;b.commands.formatInline.exec(c,a,d,h,/non-matching-class/g);j=i.querySelectorAll(d+"."+h);for(h=j.length;k<h;k++)for(p in n=j[k],n.removeAttribute("class"),g)n.setAttribute(p,g[p]);k=n;1===h&&(p=e.getTextContent(n),h=!!n.querySelector("*"),p=""===p||p===b.INVISIBLE_SPACE,!h&&p&&(e.setTextContent(n,g.text||n.href),i=i.createTextNode(" "),c.selection.setAfter(n),c.selection.insertNode(i),k=i));c.selection.setAfter(k)}
var a,d="A",e=b.dom;b.commands.createLink={exec:function(a,b,d){var h=this.state(a,b);h?a.selection.executeAndRestore(function(){for(var a=h.length,b=0,c,d,f;b<a;b++)c=h[b],d=e.getParentElement(c,{nodeName:"code"}),f=e.getTextContent(c),f.match(e.autoLink.URL_REG_EXP)&&!d?e.renameElement(c,"code"):e.replaceWithChildNodes(c)}):(d="object"===typeof d?d:{href:d},c(a,d))},state:function(a,c){return b.commands.formatInline.state(a,c,"A")},value:function(){return a}}})(wysihtml5);
(function(b){var c=/wysiwyg-font-size-[a-z\-]+/g;b.commands.fontSize={exec:function(a,d,e){return b.commands.formatInline.exec(a,d,"span","wysiwyg-font-size-"+e,c)},state:function(a,d,e){return b.commands.formatInline.state(a,d,"span","wysiwyg-font-size-"+e,c)},value:function(){}}})(wysihtml5);
(function(b){var c=/wysiwyg-color-[a-z]+/g;b.commands.foreColor={exec:function(a,d,e){return b.commands.formatInline.exec(a,d,"span","wysiwyg-color-"+e,c)},state:function(a,d,e){return b.commands.formatInline.state(a,d,"span","wysiwyg-color-"+e,c)},value:function(){}}})(wysihtml5);
(function(b){function c(a){for(a=a.previousSibling;a&&a.nodeType===b.TEXT_NODE&&!b.lang.string(a.data).trim();)a=a.previousSibling;return a}function a(a){for(a=a.nextSibling;a&&a.nodeType===b.TEXT_NODE&&!b.lang.string(a.data).trim();)a=a.nextSibling;return a}function d(a){return"BR"===a.nodeName||"block"===g.getStyle("display").from(a)?!0:!1}function e(a,c,d,e){if(e)var f=g.observe(a,"DOMNodeInserted",function(a){var a=a.target,c;a.nodeType===b.ELEMENT_NODE&&(c=g.getStyle("display").from(a),"inline"!==
c.substr(0,6)&&(a.className+=" "+e))});a.execCommand(c,!1,d);f&&f.stop()}function f(b,d){b.selection.selectLine();b.selection.surround(d);var e=a(d),f=c(d);e&&"BR"===e.nodeName&&e.parentNode.removeChild(e);f&&"BR"===f.nodeName&&f.parentNode.removeChild(f);(e=d.lastChild)&&"BR"===e.nodeName&&e.parentNode.removeChild(e);b.selection.selectNode(d)}var g=b.dom,i="H1 H2 H3 H4 H5 H6 P BLOCKQUOTE DIV".split(" ");b.commands.formatBlock={exec:function(h,k,j,n,p){var q=h.doc,r=this.state(h,k,j,n,p),m,j="string"===
typeof j?j.toUpperCase():j;if(r)h.selection.executeAndRestoreSimple(function(){p&&(r.className=r.className.replace(p,""));var e=!!b.lang.string(r.className).trim();if(!e&&r.nodeName===(j||"DIV")){var e=r,f=e.ownerDocument,h=a(e),i=c(e);h&&!d(h)&&e.parentNode.insertBefore(f.createElement("br"),h);i&&!d(i)&&e.parentNode.insertBefore(f.createElement("br"),e);g.replaceWithChildNodes(r)}else e&&g.renameElement(r,"DIV")});else{if(null===j||b.lang.array(i).contains(j))if(m=h.selection.getSelectedNode(),
r=g.getParentElement(m,{nodeName:i})){h.selection.executeAndRestoreSimple(function(){j&&(r=g.renameElement(r,j));if(n){var a=r;a.className?(a.className=a.className.replace(p,""),a.className+=" "+n):a.className=n}});return}h.commands.support(k)?e(q,k,j||"DIV",n):(r=q.createElement(j||"DIV"),n&&(r.className=n),f(h,r))}},state:function(a,b,c,d,e){c="string"===typeof c?c.toUpperCase():c;a=a.selection.getSelectedNode();return g.getParentElement(a,{nodeName:c,className:d,classRegExp:e})},value:function(){}}})(wysihtml5);
(function(b){function c(c,f,g){var i=c+":"+f;if(!d[i]){var h=d,k=b.selection.HTMLApplier,j=a[c],c=j?[c.toLowerCase(),j.toLowerCase()]:[c.toLowerCase()];h[i]=new k(c,f,g,!0)}return d[i]}var a={strong:"b",em:"i",b:"strong",i:"em"},d={};b.commands.formatInline={exec:function(a,b,d,i,h){b=a.selection.getRange();if(!b)return!1;c(d,i,h).toggleRange(b);a.selection.setSelection(b)},state:function(d,f,g,i,h){var f=d.doc,k=a[g]||g;if(!b.dom.hasElementWithTagName(f,g)&&!b.dom.hasElementWithTagName(f,k)||i&&
!b.dom.hasElementWithClassName(f,i))return!1;d=d.selection.getRange();return!d?!1:c(g,i,h).isAppliedToRange(d)},value:function(){}}})(wysihtml5);(function(b){b.commands.insertHTML={exec:function(b,a,d){b.commands.support(a)?b.doc.execCommand(a,!1,d):b.selection.insertHTML(d)},state:function(){return!1},value:function(){}}})(wysihtml5);
(function(b){b.commands.insertImage={exec:function(c,a,d){var d="object"===typeof d?d:{src:d},e=c.doc,a=this.state(c),f;if(a)c.selection.setBefore(a),d=a.parentNode,d.removeChild(a),b.dom.removeEmptyTextNodes(d),"A"===d.nodeName&&!d.firstChild&&(c.selection.setAfter(d),d.parentNode.removeChild(d)),b.quirks.redraw(c.element);else{a=e.createElement("IMG");for(f in d)a[f]=d[f];c.selection.insertNode(a);b.browser.hasProblemsSettingCaretAfterImg()?(d=e.createTextNode(b.INVISIBLE_SPACE),c.selection.insertNode(d),
c.selection.setAfter(d)):c.selection.setAfter(a)}},state:function(c){var a;if(!b.dom.hasElementWithTagName(c.doc,"IMG"))return!1;a=c.selection.getSelectedNode();if(!a)return!1;if("IMG"===a.nodeName)return a;if(a.nodeType!==b.ELEMENT_NODE)return!1;a=c.selection.getText();if(a=b.lang.string(a).trim())return!1;c=c.selection.getNodes(b.ELEMENT_NODE,function(a){return"IMG"===a.nodeName});return 1!==c.length?!1:c[0]},value:function(b){return(b=this.state(b))&&b.src}}})(wysihtml5);
(function(b){var c="<br>"+(b.browser.needsSpaceAfterLineBreak()?" ":"");b.commands.insertLineBreak={exec:function(a,d){a.commands.support(d)?(a.doc.execCommand(d,!1,null),b.browser.autoScrollsToCaret()||a.selection.scrollIntoView()):a.commands.exec("insertHTML",c)},state:function(){return!1},value:function(){}}})(wysihtml5);
(function(b){b.commands.insertOrderedList={exec:function(c,a){var d=c.doc,e=c.selection.getSelectedNode(),f=b.dom.getParentElement(e,{nodeName:"OL"}),g=b.dom.getParentElement(e,{nodeName:"UL"}),e="_wysihtml5-temp-"+(new Date).getTime(),i;c.commands.support(a)?d.execCommand(a,!1,null):f?c.selection.executeAndRestoreSimple(function(){b.dom.resolveList(f)}):g?c.selection.executeAndRestoreSimple(function(){b.dom.renameElement(g,"ol")}):(c.commands.exec("formatBlock","div",e),i=d.querySelector("."+e),
d=""===i.innerHTML||i.innerHTML===b.INVISIBLE_SPACE,c.selection.executeAndRestoreSimple(function(){f=b.dom.convertToList(i,"ol")}),d&&c.selection.selectNode(f.querySelector("li")))},state:function(c){c=c.selection.getSelectedNode();return b.dom.getParentElement(c,{nodeName:"OL"})},value:function(){}}})(wysihtml5);
(function(b){b.commands.insertUnorderedList={exec:function(c,a){var d=c.doc,e=c.selection.getSelectedNode(),f=b.dom.getParentElement(e,{nodeName:"UL"}),g=b.dom.getParentElement(e,{nodeName:"OL"}),e="_wysihtml5-temp-"+(new Date).getTime(),i;c.commands.support(a)?d.execCommand(a,!1,null):f?c.selection.executeAndRestoreSimple(function(){b.dom.resolveList(f)}):g?c.selection.executeAndRestoreSimple(function(){b.dom.renameElement(g,"ul")}):(c.commands.exec("formatBlock","div",e),i=d.querySelector("."+e),
d=""===i.innerHTML||i.innerHTML===b.INVISIBLE_SPACE,c.selection.executeAndRestoreSimple(function(){f=b.dom.convertToList(i,"ul")}),d&&c.selection.selectNode(f.querySelector("li")))},state:function(c){c=c.selection.getSelectedNode();return b.dom.getParentElement(c,{nodeName:"UL"})},value:function(){}}})(wysihtml5);(function(b){b.commands.italic={exec:function(c,a){return b.commands.formatInline.exec(c,a,"i")},state:function(c,a){return b.commands.formatInline.state(c,a,"i")},value:function(){}}})(wysihtml5);
(function(b){var c=/wysiwyg-text-align-[a-z]+/g;b.commands.justifyCenter={exec:function(a){return b.commands.formatBlock.exec(a,"formatBlock",null,"wysiwyg-text-align-center",c)},state:function(a){return b.commands.formatBlock.state(a,"formatBlock",null,"wysiwyg-text-align-center",c)},value:function(){}}})(wysihtml5);
(function(b){var c=/wysiwyg-text-align-[a-z]+/g;b.commands.justifyLeft={exec:function(a){return b.commands.formatBlock.exec(a,"formatBlock",null,"wysiwyg-text-align-left",c)},state:function(a){return b.commands.formatBlock.state(a,"formatBlock",null,"wysiwyg-text-align-left",c)},value:function(){}}})(wysihtml5);
(function(b){var c=/wysiwyg-text-align-[a-z]+/g;b.commands.justifyRight={exec:function(a){return b.commands.formatBlock.exec(a,"formatBlock",null,"wysiwyg-text-align-right",c)},state:function(a){return b.commands.formatBlock.state(a,"formatBlock",null,"wysiwyg-text-align-right",c)},value:function(){}}})(wysihtml5);(function(b){b.commands.underline={exec:function(c,a){return b.commands.formatInline.exec(c,a,"u")},state:function(c,a){return b.commands.formatInline.state(c,a,"u")},value:function(){}}})(wysihtml5);
(function(b){var c='<span id="_wysihtml5-undo" class="_wysihtml5-temp">'+b.INVISIBLE_SPACE+"</span>",a='<span id="_wysihtml5-redo" class="_wysihtml5-temp">'+b.INVISIBLE_SPACE+"</span>",d=b.dom;b.UndoManager=b.lang.Dispatcher.extend({constructor:function(a){this.editor=a;this.composer=a.composer;this.element=this.composer.element;this.history=[this.composer.getValue()];this.position=1;this.composer.commands.support("insertHTML")&&this._observe()},_observe:function(){var e=this,f=this.composer.sandbox.getDocument(),
g;d.observe(this.element,"keydown",function(a){if(!(a.altKey||!a.ctrlKey&&!a.metaKey)){var b=a.keyCode,c=90===b&&a.shiftKey||89===b;90===b&&!a.shiftKey?(e.undo(),a.preventDefault()):c&&(e.redo(),a.preventDefault())}});d.observe(this.element,"keydown",function(a){a=a.keyCode;a!==g&&(g=a,(8===a||46===a)&&e.transact())});if(b.browser.hasUndoInContextMenu()){var i,h,k=function(){for(var a;a=f.querySelector("._wysihtml5-temp");)a.parentNode.removeChild(a);clearInterval(i)};d.observe(this.element,"contextmenu",
function(){k();e.composer.selection.executeAndRestoreSimple(function(){e.element.lastChild&&e.composer.selection.setAfter(e.element.lastChild);f.execCommand("insertHTML",!1,c);f.execCommand("insertHTML",!1,a);f.execCommand("undo",!1,null)});i=setInterval(function(){f.getElementById("_wysihtml5-redo")?(k(),e.redo()):f.getElementById("_wysihtml5-undo")||(k(),e.undo())},400);h||(h=!0,d.observe(document,"mousedown",k),d.observe(f,["mousedown","paste","cut","copy"],k))})}this.editor.observe("newword:composer",
function(){e.transact()}).observe("beforecommand:composer",function(){e.transact()})},transact:function(){var a=this.history[this.position-1],b=this.composer.getValue();if(b!=a){if(40<(this.history.length=this.position))this.history.shift(),this.position--;this.position++;this.history.push(b)}},undo:function(){this.transact();1>=this.position||(this.set(this.history[--this.position-1]),this.editor.fire("undo:composer"))},redo:function(){this.position>=this.history.length||(this.set(this.history[++this.position-
1]),this.editor.fire("redo:composer"))},set:function(a){this.composer.setValue(a);this.editor.focus(!0)}})})(wysihtml5);
wysihtml5.views.View=Base.extend({constructor:function(b,c,a){this.parent=b;this.element=c;this.config=a;this._observeViewChange()},_observeViewChange:function(){var b=this;this.parent.observe("beforeload",function(){b.parent.observe("change_view",function(c){c===b.name?(b.parent.currentView=b,b.show(),setTimeout(function(){b.focus()},0)):b.hide()})})},focus:function(){if(this.element.ownerDocument.querySelector(":focus")!==this.element)try{this.element.focus()}catch(b){}},hide:function(){this.element.style.display=
"none"},show:function(){this.element.style.display=""},disable:function(){this.element.setAttribute("disabled","disabled")},enable:function(){this.element.removeAttribute("disabled")}});
(function(b){var c=b.dom,a=b.browser;b.views.Composer=b.views.View.extend({name:"composer",CARET_HACK:"<br>",constructor:function(a,b,c){this.base(a,b,c);this.textarea=this.parent.textarea;this._initSandbox()},clear:function(){this.element.innerHTML=a.displaysCaretInEmptyContentEditableCorrectly()?"":this.CARET_HACK},getValue:function(a){var c=this.isEmpty()?"":b.quirks.getCorrectInnerHTML(this.element);a&&(c=this.parent.parse(c));return c=b.lang.string(c).replace(b.INVISIBLE_SPACE).by("")},setValue:function(a,
b){b&&(a=this.parent.parse(a));this.element.innerHTML=a},show:function(){this.iframe.style.display=this._displayStyle||"";this.disable();this.enable()},hide:function(){this._displayStyle=c.getStyle("display").from(this.iframe);"none"===this._displayStyle&&(this._displayStyle=null);this.iframe.style.display="none"},disable:function(){this.element.removeAttribute("contentEditable");this.base()},enable:function(){this.element.setAttribute("contentEditable","true");this.base()},focus:function(a){b.browser.doesAsyncFocus()&&
this.hasPlaceholderSet()&&this.clear();this.base();var c=this.element.lastChild;a&&c&&("BR"===c.nodeName?this.selection.setBefore(this.element.lastChild):this.selection.setAfter(this.element.lastChild))},getTextContent:function(){return c.getTextContent(this.element)},hasPlaceholderSet:function(){return this.getTextContent()==this.textarea.element.getAttribute("placeholder")},isEmpty:function(){var a=this.element.innerHTML;return""===a||a===this.CARET_HACK||this.hasPlaceholderSet()||""===this.getTextContent()&&
!this.element.querySelector("blockquote, ul, ol, img, embed, object, table, iframe, svg, video, audio, button, input, select, textarea")},_initSandbox:function(){var a=this;this.sandbox=new c.Sandbox(function(){a._create()},{stylesheets:this.config.stylesheets});this.iframe=this.sandbox.getIframe();var b=document.createElement("input");b.type="hidden";b.name="_wysihtml5_mode";b.value=1;var f=this.textarea.element;c.insert(this.iframe).after(f);c.insert(b).after(f)},_create:function(){var d=this;this.doc=
this.sandbox.getDocument();this.element=this.doc.body;this.textarea=this.parent.textarea;this.element.innerHTML=this.textarea.getValue(!0);this.enable();this.selection=new b.Selection(this.parent);this.commands=new b.Commands(this.parent);c.copyAttributes("className spellcheck title lang dir accessKey".split(" ")).from(this.textarea.element).to(this.element);c.addClass(this.element,this.config.composerClassName);this.config.style&&this.style();this.observe();var e=this.config.name;e&&(c.addClass(this.element,
e),c.addClass(this.iframe,e));(e="string"===typeof this.config.placeholder?this.config.placeholder:this.textarea.element.getAttribute("placeholder"))&&c.simulatePlaceholder(this.parent,this,e);this.commands.exec("styleWithCSS",!1);this._initAutoLinking();this._initObjectResizing();this._initUndoManager();(this.textarea.element.hasAttribute("autofocus")||document.querySelector(":focus")==this.textarea.element)&&setTimeout(function(){d.focus()},100);b.quirks.insertLineBreakOnReturn(this);a.clearsContentEditableCorrectly()||
b.quirks.ensureProperClearing(this);a.clearsListsInContentEditableCorrectly()||b.quirks.ensureProperClearingOfLists(this);this.initSync&&this.config.sync&&this.initSync();this.textarea.hide();this.parent.fire("beforeload").fire("load")},_initAutoLinking:function(){var d=this,e=a.canDisableAutoLinking(),f=a.doesAutoLinkingInContentEditable();e&&this.commands.exec("autoUrlDetect",!1);if(this.config.autoLink){(!f||f&&e)&&this.parent.observe("newword:composer",function(){d.selection.executeAndRestore(function(a,
b){c.autoLink(b.parentNode)})});var g=this.sandbox.getDocument().getElementsByTagName("a"),i=c.autoLink.URL_REG_EXP,h=function(a){a=b.lang.string(c.getTextContent(a)).trim();"www."===a.substr(0,4)&&(a="http://"+a);return a};c.observe(this.element,"keydown",function(a){if(g.length){var a=d.selection.getSelectedNode(a.target.ownerDocument),b=c.getParentElement(a,{nodeName:"A"},4),e;b&&(e=h(b),setTimeout(function(){var a=h(b);a!==e&&a.match(i)&&b.setAttribute("href",a)},0))}})}},_initObjectResizing:function(){var d=
["width","height"],e=d.length,f=this.element;this.commands.exec("enableObjectResizing",this.config.allowObjectResizing);this.config.allowObjectResizing?a.supportsEvent("resizeend")&&c.observe(f,"resizeend",function(a){for(var a=a.target||a.srcElement,c=a.style,h=0,k;h<e;h++)k=d[h],c[k]&&(a.setAttribute(k,parseInt(c[k],10)),c[k]="");b.quirks.redraw(f)}):a.supportsEvent("resizestart")&&c.observe(f,"resizestart",function(a){a.preventDefault()})},_initUndoManager:function(){new b.UndoManager(this.parent)}})})(wysihtml5);
(function(b){var c=b.dom,a=document,d=window,e=a.createElement("div"),f="background-color color cursor font-family font-size font-style font-variant font-weight line-height letter-spacing text-align text-decoration text-indent text-rendering word-break word-wrap word-spacing".split(" "),g="background-color border-collapse border-bottom-color border-bottom-style border-bottom-width border-left-color border-left-style border-left-width border-right-color border-right-style border-right-width border-top-color border-top-style border-top-width clear display float margin-bottom margin-left margin-right margin-top outline-color outline-offset outline-width outline-style padding-left padding-right padding-top padding-bottom position top left right bottom z-index vertical-align text-align -webkit-box-sizing -moz-box-sizing -ms-box-sizing box-sizing -webkit-box-shadow -moz-box-shadow -ms-box-shadow box-shadow -webkit-border-top-right-radius -moz-border-radius-topright border-top-right-radius -webkit-border-bottom-right-radius -moz-border-radius-bottomright border-bottom-right-radius -webkit-border-bottom-left-radius -moz-border-radius-bottomleft border-bottom-left-radius -webkit-border-top-left-radius -moz-border-radius-topleft border-top-left-radius width height".split(" "),
i="width height top left right bottom".split(" "),h=["html { height: 100%; }","body { min-height: 100%; padding: 0; margin: 0; margin-top: -1px; padding-top: 1px; }","._wysihtml5-temp { display: none; }",b.browser.isGecko?"body.placeholder { color: graytext !important; }":"body.placeholder { color: #a9a9a9 !important; }","body[disabled] { background-color: #eee !important; color: #999 !important; cursor: default !important; }","img:-moz-broken { -moz-force-broken-image-icon: 1; height: 24px; width: 24px; }"],
k=function(b){if(b.setActive)try{b.setActive()}catch(e){}else{var f=b.style,h=a.documentElement.scrollTop||a.body.scrollTop,g=a.documentElement.scrollLeft||a.body.scrollLeft,f={position:f.position,top:f.top,left:f.left,WebkitUserSelect:f.WebkitUserSelect};c.setStyles({position:"absolute",top:"-99999px",left:"-99999px",WebkitUserSelect:"none"}).on(b);b.focus();c.setStyles(f).on(b);d.scrollTo&&d.scrollTo(g,h)}};b.views.Composer.prototype.style=function(){var j=this,n=a.querySelector(":focus"),p=this.textarea.element,
q=p.hasAttribute("placeholder"),r=q&&p.getAttribute("placeholder");this.focusStylesHost=this.focusStylesHost||e.cloneNode(!1);this.blurStylesHost=this.blurStylesHost||e.cloneNode(!1);q&&p.removeAttribute("placeholder");p===n&&p.blur();c.copyStyles(g).from(p).to(this.iframe).andTo(this.blurStylesHost);c.copyStyles(f).from(p).to(this.element).andTo(this.blurStylesHost);c.insertCSS(h).into(this.element.ownerDocument);k(p);c.copyStyles(g).from(p).to(this.focusStylesHost);c.copyStyles(f).from(p).to(this.focusStylesHost);
var m=b.lang.array(g).without(["display"]);n?n.focus():p.blur();q&&p.setAttribute("placeholder",r);if(!b.browser.hasCurrentStyleProperty())var s=c.observe(d,"resize",function(){if(c.contains(document.documentElement,j.iframe)){var a=c.getStyle("display").from(p),b=c.getStyle("display").from(j.iframe);p.style.display="";j.iframe.style.display="none";c.copyStyles(i).from(p).to(j.iframe).andTo(j.focusStylesHost).andTo(j.blurStylesHost);j.iframe.style.display=b;p.style.display=a}else s.stop()});this.parent.observe("focus:composer",
function(){c.copyStyles(m).from(j.focusStylesHost).to(j.iframe);c.copyStyles(f).from(j.focusStylesHost).to(j.element)});this.parent.observe("blur:composer",function(){c.copyStyles(m).from(j.blurStylesHost).to(j.iframe);c.copyStyles(f).from(j.blurStylesHost).to(j.element)});return this}})(wysihtml5);
(function(b){var c=b.dom,a=b.browser,d={66:"bold",73:"italic",85:"underline"};b.views.Composer.prototype.observe=function(){var e=this,f=this.getValue(),g=this.sandbox.getIframe(),i=this.element,h=a.supportsEventsInIframeCorrectly()?i:this.sandbox.getWindow(),k=a.supportsEvent("drop")?["drop","paste"]:["dragdrop","paste"];c.observe(g,"DOMNodeRemoved",function(){clearInterval(j);e.parent.fire("destroy:composer")});var j=setInterval(function(){c.contains(document.documentElement,g)||(clearInterval(j),
e.parent.fire("destroy:composer"))},250);c.observe(h,"focus",function(){e.parent.fire("focus").fire("focus:composer");setTimeout(function(){f=e.getValue()},0)});c.observe(h,"blur",function(){f!==e.getValue()&&e.parent.fire("change").fire("change:composer");e.parent.fire("blur").fire("blur:composer")});b.browser.isIos()&&c.observe(i,"blur",function(){var a=i.ownerDocument.createElement("input"),b=document.documentElement.scrollTop||document.body.scrollTop,c=document.documentElement.scrollLeft||document.body.scrollLeft;
try{e.selection.insertNode(a)}catch(d){i.appendChild(a)}a.focus();a.parentNode.removeChild(a);window.scrollTo(c,b)});c.observe(i,"dragenter",function(){e.parent.fire("unset_placeholder")});a.firesOnDropOnlyWhenOnDragOverIsCancelled()&&c.observe(i,["dragover","dragenter"],function(a){a.preventDefault()});c.observe(i,k,function(b){var c=b.dataTransfer,d;c&&a.supportsDataTransfer()&&(d=c.getData("text/html")||c.getData("text/plain"));d?(i.focus(),e.commands.exec("insertHTML",d),e.parent.fire("paste").fire("paste:composer"),
b.stopPropagation(),b.preventDefault()):setTimeout(function(){e.parent.fire("paste").fire("paste:composer")},0)});c.observe(i,"keyup",function(a){a=a.keyCode;(a===b.SPACE_KEY||a===b.ENTER_KEY)&&e.parent.fire("newword:composer")});this.parent.observe("paste:composer",function(){setTimeout(function(){e.parent.fire("newword:composer")},0)});a.canSelectImagesInContentEditable()||c.observe(i,"mousedown",function(a){var b=a.target;"IMG"===b.nodeName&&(e.selection.selectNode(b),a.preventDefault())});c.observe(i,
"keydown",function(a){var b=d[a.keyCode];if((a.ctrlKey||a.metaKey)&&!a.altKey&&b)e.commands.exec(b),a.preventDefault()});c.observe(i,"keydown",function(a){var c=e.selection.getSelectedNode(!0),d=a.keyCode;if(c&&"IMG"===c.nodeName&&(d===b.BACKSPACE_KEY||d===b.DELETE_KEY))d=c.parentNode,d.removeChild(c),"A"===d.nodeName&&!d.firstChild&&d.parentNode.removeChild(d),setTimeout(function(){b.quirks.redraw(i)},0),a.preventDefault()});var n={IMG:"Image: ",A:"Link: "};c.observe(i,"mouseover",function(a){var a=
a.target,b=a.nodeName;!("A"!==b&&"IMG"!==b)&&!a.hasAttribute("title")&&(b=n[b]+(a.getAttribute("href")||a.getAttribute("src")),a.setAttribute("title",b))})}})(wysihtml5);
(function(b){b.views.Synchronizer=Base.extend({constructor:function(b,a,d){this.editor=b;this.textarea=a;this.composer=d;this._observe()},fromComposerToTextarea:function(c){this.textarea.setValue(b.lang.string(this.composer.getValue()).trim(),c)},fromTextareaToComposer:function(b){var a=this.textarea.getValue();a?this.composer.setValue(a,b):(this.composer.clear(),this.editor.fire("set_placeholder"))},sync:function(b){"textarea"===this.editor.currentView.name?this.fromTextareaToComposer(b):this.fromComposerToTextarea(b)},
_observe:function(){var c,a=this,d=this.textarea.element.form,e=function(){c=setInterval(function(){a.fromComposerToTextarea()},400)},f=function(){clearInterval(c);c=null};e();d&&(b.dom.observe(d,"submit",function(){a.sync(!0)}),b.dom.observe(d,"reset",function(){setTimeout(function(){a.fromTextareaToComposer()},0)}));this.editor.observe("change_view",function(b){if(b==="composer"&&!c){a.fromTextareaToComposer(true);e()}else if(b==="textarea"){a.fromComposerToTextarea(true);f()}});this.editor.observe("destroy:composer",
f)}})})(wysihtml5);
wysihtml5.views.Textarea=wysihtml5.views.View.extend({name:"textarea",constructor:function(b,c,a){this.base(b,c,a);this._observe()},clear:function(){this.element.value=""},getValue:function(b){var c=this.isEmpty()?"":this.element.value;b&&(c=this.parent.parse(c));return c},setValue:function(b,c){c&&(b=this.parent.parse(b));this.element.value=b},hasPlaceholderSet:function(){var b=wysihtml5.browser.supportsPlaceholderAttributeOn(this.element),c=this.element.getAttribute("placeholder")||null,a=this.element.value;
return b&&!a||a===c},isEmpty:function(){return!wysihtml5.lang.string(this.element.value).trim()||this.hasPlaceholderSet()},_observe:function(){var b=this.element,c=this.parent,a={focusin:"focus",focusout:"blur"},d=wysihtml5.browser.supportsEvent("focusin")?["focusin","focusout","change"]:["focus","blur","change"];c.observe("beforeload",function(){wysihtml5.dom.observe(b,d,function(b){b=a[b.type]||b.type;c.fire(b).fire(b+":textarea")});wysihtml5.dom.observe(b,["paste","drop"],function(){setTimeout(function(){c.fire("paste").fire("paste:textarea")},
0)})})}});
(function(b){var c=b.dom;b.toolbar.Dialog=b.lang.Dispatcher.extend({constructor:function(a,b){this.link=a;this.container=b},_observe:function(){if(!this._observed){var a=this,d=function(b){var c=a._serialize();c==a.elementToChange?a.fire("edit",c):a.fire("save",c);a.hide();b.preventDefault();b.stopPropagation()};c.observe(a.link,"click",function(){c.hasClass(a.link,"wysihtml5-command-dialog-opened")&&setTimeout(function(){a.hide()},0)});c.observe(this.container,"keydown",function(c){var e=c.keyCode;
e===b.ENTER_KEY&&d(c);e===b.ESCAPE_KEY&&a.hide()});c.delegate(this.container,"[data-wysihtml5-dialog-action=save]","click",d);c.delegate(this.container,"[data-wysihtml5-dialog-action=cancel]","click",function(b){a.fire("cancel");a.hide();b.preventDefault();b.stopPropagation()});for(var e=this.container.querySelectorAll("input, select, textarea"),f=0,g=e.length,i=function(){clearInterval(a.interval)};f<g;f++)c.observe(e[f],"change",i);this._observed=!0}},_serialize:function(){for(var a=this.elementToChange||
{},b=this.container.querySelectorAll("[data-wysihtml5-dialog-field]"),c=b.length,f=0;f<c;f++)a[b[f].getAttribute("data-wysihtml5-dialog-field")]=b[f].value;return a},_interpolate:function(a){for(var b,c,f=document.querySelector(":focus"),g=this.container.querySelectorAll("[data-wysihtml5-dialog-field]"),i=g.length,h=0;h<i;h++)b=g[h],b!==f&&!(a&&"hidden"===b.type)&&(c=b.getAttribute("data-wysihtml5-dialog-field"),c=this.elementToChange?this.elementToChange[c]||"":b.defaultValue,b.value=c)},show:function(a){var b=
this,e=this.container.querySelector("input, select, textarea");this.elementToChange=a;this._observe();this._interpolate();a&&(this.interval=setInterval(function(){b._interpolate(!0)},500));c.addClass(this.link,"wysihtml5-command-dialog-opened");this.container.style.display="";this.fire("show");if(e&&!a)try{e.focus()}catch(f){}},hide:function(){clearInterval(this.interval);this.elementToChange=null;c.removeClass(this.link,"wysihtml5-command-dialog-opened");this.container.style.display="none";this.fire("hide")}})})(wysihtml5);
(function(b){var c=b.dom,a={position:"relative"},d={left:0,margin:0,opacity:0,overflow:"hidden",padding:0,position:"absolute",top:0,zIndex:1},e={cursor:"inherit",fontSize:"50px",height:"50px",marginTop:"-25px",outline:0,padding:0,position:"absolute",right:"-4px",top:"50%"},f={"x-webkit-speech":"",speech:""};b.toolbar.Speech=function(g,i){var h=document.createElement("input");if(b.browser.supportsSpeechApiOn(h)){var k=document.createElement("div");b.lang.object(d).merge({width:i.offsetWidth+"px",height:i.offsetHeight+
"px"});c.insert(h).into(k);c.insert(k).into(i);c.setStyles(e).on(h);c.setAttributes(f).on(h);c.setStyles(d).on(k);c.setStyles(a).on(i);c.observe(h,"onwebkitspeechchange"in h?"webkitspeechchange":"speechchange",function(){g.execCommand("insertText",h.value);h.value=""});c.observe(h,"click",function(a){c.hasClass(i,"wysihtml5-command-disabled")&&a.preventDefault();a.stopPropagation()})}else i.style.display="none"}})(wysihtml5);
(function(b){var c=b.dom;b.toolbar.Toolbar=Base.extend({constructor:function(a,c){this.editor=a;this.container="string"===typeof c?document.getElementById(c):c;this.composer=a.composer;this._getLinks("command");this._getLinks("action");this._observe();this.show();for(var e=this.container.querySelectorAll("[data-wysihtml5-command=insertSpeech]"),f=e.length,g=0;g<f;g++)new b.toolbar.Speech(this,e[g])},_getLinks:function(a){for(var c=this[a+"Links"]=b.lang.array(this.container.querySelectorAll("[data-wysihtml5-"+
a+"]")).get(),e=c.length,f=0,g=this[a+"Mapping"]={},i,h,k,j,n;f<e;f++)i=c[f],k=i.getAttribute("data-wysihtml5-"+a),j=i.getAttribute("data-wysihtml5-"+a+"-value"),h=this.container.querySelector("[data-wysihtml5-"+a+"-group='"+k+"']"),n=this._getDialog(i,k),g[k+":"+j]={link:i,group:h,name:k,value:j,dialog:n,state:!1}},_getDialog:function(a,c){var e=this,f=this.container.querySelector("[data-wysihtml5-dialog='"+c+"']"),g,i;f&&(g=new b.toolbar.Dialog(a,f),g.observe("show",function(){i=e.composer.selection.getBookmark();
e.editor.fire("show:dialog",{command:c,dialogContainer:f,commandLink:a})}),g.observe("save",function(b){i&&e.composer.selection.setBookmark(i);e._execCommand(c,b);e.editor.fire("save:dialog",{command:c,dialogContainer:f,commandLink:a})}),g.observe("cancel",function(){e.editor.focus(!1);e.editor.fire("cancel:dialog",{command:c,dialogContainer:f,commandLink:a})}));return g},execCommand:function(a,b){if(!this.commandsDisabled){var c=this.commandMapping[a+":"+b];c&&c.dialog&&!c.state?c.dialog.show():
this._execCommand(a,b)}},_execCommand:function(a,b){this.editor.focus(!1);this.composer.commands.exec(a,b);this._updateLinkStates()},execAction:function(a){var b=this.editor;switch(a){case "change_view":b.currentView===b.textarea?b.fire("change_view","composer"):b.fire("change_view","textarea")}},_observe:function(){for(var a=this,b=this.editor,e=this.container,f=this.commandLinks.concat(this.actionLinks),g=f.length,i=0;i<g;i++)c.setAttributes({href:"javascript:;",unselectable:"on"}).on(f[i]);c.delegate(e,
"[data-wysihtml5-command]","mousedown",function(a){a.preventDefault()});c.delegate(e,"[data-wysihtml5-command]","click",function(b){var c=this.getAttribute("data-wysihtml5-command"),d=this.getAttribute("data-wysihtml5-command-value");a.execCommand(c,d);b.preventDefault()});c.delegate(e,"[data-wysihtml5-action]","click",function(b){var c=this.getAttribute("data-wysihtml5-action");a.execAction(c);b.preventDefault()});b.observe("focus:composer",function(){a.bookmark=null;clearInterval(a.interval);a.interval=
setInterval(function(){a._updateLinkStates()},500)});b.observe("blur:composer",function(){clearInterval(a.interval)});b.observe("destroy:composer",function(){clearInterval(a.interval)});b.observe("change_view",function(b){setTimeout(function(){a.commandsDisabled="composer"!==b;a._updateLinkStates();a.commandsDisabled?c.addClass(e,"wysihtml5-commands-disabled"):c.removeClass(e,"wysihtml5-commands-disabled")},0)})},_updateLinkStates:function(){var a=this.commandMapping,d=this.actionMapping,e,f,g;for(e in a)if(g=
a[e],this.commandsDisabled?(f=!1,c.removeClass(g.link,"wysihtml5-command-active"),g.group&&c.removeClass(g.group,"wysihtml5-command-active"),g.dialog&&g.dialog.hide()):(f=this.composer.commands.state(g.name,g.value),b.lang.object(f).isArray()&&(f=1===f.length?f[0]:!0),c.removeClass(g.link,"wysihtml5-command-disabled"),g.group&&c.removeClass(g.group,"wysihtml5-command-disabled")),g.state!==f)(g.state=f)?(c.addClass(g.link,"wysihtml5-command-active"),g.group&&c.addClass(g.group,"wysihtml5-command-active"),
g.dialog&&("object"===typeof f?g.dialog.show(f):g.dialog.hide())):(c.removeClass(g.link,"wysihtml5-command-active"),g.group&&c.removeClass(g.group,"wysihtml5-command-active"),g.dialog&&g.dialog.hide());for(e in d)a=d[e],"change_view"===a.name&&(a.state=this.editor.currentView===this.editor.textarea,a.state?c.addClass(a.link,"wysihtml5-action-active"):c.removeClass(a.link,"wysihtml5-action-active"))},show:function(){this.container.style.display=""},hide:function(){this.container.style.display="none"}})})(wysihtml5);
(function(b){var c={name:void 0,style:!0,toolbar:void 0,autoLink:!0,parserRules:{tags:{br:{},span:{},div:{},p:{}},classes:{}},parser:b.dom.parse,composerClassName:"wysihtml5-editor",bodyClassName:"wysihtml5-supported",stylesheets:[],placeholderText:void 0,allowObjectResizing:!0,supportTouchDevices:!0};b.Editor=b.lang.Dispatcher.extend({constructor:function(a,d){this.textareaElement="string"===typeof a?document.getElementById(a):a;this.config=b.lang.object({}).merge(c).merge(d).get();this.currentView=
this.textarea=new b.views.Textarea(this,this.textareaElement,this.config);this._isCompatible=b.browser.supported();if(!this._isCompatible||!this.config.supportTouchDevices&&b.browser.isTouchDevice()){var e=this;setTimeout(function(){e.fire("beforeload").fire("load")},0)}else{b.dom.addClass(document.body,this.config.bodyClassName);this.currentView=this.composer=new b.views.Composer(this,this.textareaElement,this.config);"function"===typeof this.config.parser&&this._initParser();this.observe("beforeload",
function(){this.synchronizer=new b.views.Synchronizer(this,this.textarea,this.composer);this.config.toolbar&&(this.toolbar=new b.toolbar.Toolbar(this,this.config.toolbar))});try{console.log("Heya! This page is using wysihtml5 for rich text editing. Check out https://github.com/xing/wysihtml5")}catch(f){}}},isCompatible:function(){return this._isCompatible},clear:function(){this.currentView.clear();return this},getValue:function(a){return this.currentView.getValue(a)},setValue:function(a,b){if(!a)return this.clear();
this.currentView.setValue(a,b);return this},focus:function(a){this.currentView.focus(a);return this},disable:function(){this.currentView.disable();return this},enable:function(){this.currentView.enable();return this},isEmpty:function(){return this.currentView.isEmpty()},hasPlaceholderSet:function(){return this.currentView.hasPlaceholderSet()},parse:function(a){var c=this.config.parser(a,this.config.parserRules,this.composer.sandbox.getDocument(),!0);"object"===typeof a&&b.quirks.redraw(a);return c},
_initParser:function(){this.observe("paste:composer",function(){var a=this;a.composer.selection.executeAndRestore(function(){b.quirks.cleanPastedHTML(a.composer.element);a.parse(a.composer.element)},!0)});this.observe("paste:textarea",function(){this.textarea.setValue(this.parse(this.textarea.getValue()))})}})})(wysihtml5);

@ -0,0 +1,67 @@
.wysiwyg-color-black {
color: black;
}
.wysiwyg-color-silver {
color: silver;
}
.wysiwyg-color-gray {
color: gray;
}
.wysiwyg-color-white {
color: white;
}
.wysiwyg-color-maroon {
color: maroon;
}
.wysiwyg-color-red {
color: red;
}
.wysiwyg-color-purple {
color: purple;
}
.wysiwyg-color-fuchsia {
color: fuchsia;
}
.wysiwyg-color-green {
color: green;
}
.wysiwyg-color-lime {
color: lime;
}
.wysiwyg-color-olive {
color: olive;
}
.wysiwyg-color-yellow {
color: yellow;
}
.wysiwyg-color-navy {
color: navy;
}
.wysiwyg-color-blue {
color: blue;
}
.wysiwyg-color-teal {
color: teal;
}
.wysiwyg-color-aqua {
color: aqua;
}
.wysiwyg-color-orange {
color: orange;
}

@ -0,0 +1,119 @@
/**
Bootstrap wysihtml5 editor. Based on [bootstrap-wysihtml5](https://github.com/jhollingworth/bootstrap-wysihtml5).
You should include this input **manually** with dependent js and css files from `inputs-ext` directory.
<link href="js/inputs-ext/wysihtml5/bootstrap-wysihtml5-0.0.2/bootstrap-wysihtml5-0.0.2.css" rel="stylesheet" type="text/css"></link>
<script src="js/inputs-ext/wysihtml5/bootstrap-wysihtml5-0.0.2/wysihtml5-0.3.0.min.js"></script>
<script src="js/inputs-ext/wysihtml5/bootstrap-wysihtml5-0.0.2/bootstrap-wysihtml5-0.0.2.min.js"></script>
<script src="js/inputs-ext/wysihtml5/wysihtml5.js"></script>
@class wysihtml5
@extends abstractinput
@final
@since 1.4.0
@example
<div id="comments" data-type="wysihtml5" data-pk="1"><h2>awesome</h2> comment!</div>
<script>
$(function(){
$('#comments').editable({
url: '/post',
title: 'Enter comments'
});
});
</script>
**/
(function ($) {
var Wysihtml5 = function (options) {
this.init('wysihtml5', options, Wysihtml5.defaults);
//extend wysihtml5 manually as $.extend not recursive
this.options.wysihtml5 = $.extend({}, Wysihtml5.defaults.wysihtml5, options.wysihtml5);
};
$.fn.editableutils.inherit(Wysihtml5, $.fn.editabletypes.abstractinput);
$.extend(Wysihtml5.prototype, {
render: function () {
var deferred = $.Deferred();
//generate unique id as it required for wysihtml5
this.$input.attr('id', 'textarea_'+(new Date()).getTime());
this.setClass();
this.setAttr('placeholder');
//resolve deffered when widget loaded
$.extend(this.options.wysihtml5, {
events: {
load: function() {
deferred.resolve();
}
}
});
this.$input.wysihtml5(this.options.wysihtml5);
/*
In IE8 wysihtml5 iframe stays on the same line with buttons toolbar (inside popover).
Not pretty but working solution is to add <br>. If you fine better way, please send PR.
*/
if($.browser.msie && parseInt($.browser.version, 10) <= 8) {
this.$input.before('<br><br>');
}
return deferred.promise();
},
value2html: function(value, element) {
$(element).html(value);
},
html2value: function(html) {
return html;
},
value2input: function(value) {
this.$input.data("wysihtml5").editor.setValue(value, true);
},
activate: function() {
this.$input.data("wysihtml5").editor.focus();
}
});
Wysihtml5.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
/**
@property tpl
@default <textarea></textarea>
**/
tpl:'<textarea></textarea>',
/**
@property inputclass
@default editable-wysihtml5
**/
inputclass: 'editable-wysihtml5',
/**
Placeholder attribute of input. Shown when input is empty.
@property placeholder
@type string
@default null
**/
placeholder: null,
/**
Wysihtml5 default options.
See https://github.com/jhollingworth/bootstrap-wysihtml5#options
@property wysihtml5
@type object
@default {stylesheets: false}
**/
wysihtml5: {
stylesheets: false //see https://github.com/jhollingworth/bootstrap-wysihtml5/issues/183
}
});
$.fn.editabletypes.wysihtml5 = Wysihtml5;
}(window.jQuery));

@ -20,26 +20,27 @@ To create your own input you can inherit from this class.
**/
init: function(type, options, defaults) {
this.type = type;
this.options = $.extend({}, defaults, options);
this.$input = null;
this.$clear = null;
this.error = null;
this.options = $.extend({}, defaults, options);
},
/*
this method called before render to init $tpl that is inserted in DOM
*/
prerender: function() {
this.$tpl = $(this.options.tpl); //whole tpl as jquery object
this.$input = this.$tpl; //control itself, can be changed in render method
this.$clear = null; //clear button
this.error = null; //error message, if input cannot be rendered
},
/**
Renders input from tpl. Can return jQuery deferred object.
Can be overwritten in child objects
@method render()
**/
render: function() {
this.$input = $(this.options.tpl);
if(this.options.inputclass) {
this.$input.addClass(this.options.inputclass);
}
if (this.options.placeholder) {
this.$input.attr('placeholder', this.options.placeholder);
}
},
/**
@ -76,7 +77,7 @@ To create your own input you can inherit from this class.
},
/**
Converts string received from server into value.
Converts string received from server into value. Usually from `data-value` attribute.
@method str2value(str)
@param {string} str
@ -87,7 +88,7 @@ To create your own input you can inherit from this class.
},
/**
Converts value for submitting to server
Converts value for submitting to server. Result can be string or object.
@method value2submit(value)
@param {mixed} value
@ -148,7 +149,25 @@ To create your own input you can inherit from this class.
**/
autosubmit: function() {
},
// -------- helper functions --------
setClass: function() {
if(this.options.inputclass) {
this.$input.addClass(this.options.inputclass);
}
},
setAttr: function(attr) {
if (this.options[attr]) {
this.$input.attr(attr, this.options[attr]);
}
},
option: function(key, value) {
this.options[key] = value;
}
};
AbstractInput.defaults = {

@ -32,6 +32,9 @@ $(function(){
$.extend(Checklist.prototype, {
renderList: function() {
var $label, $div;
this.$tpl.empty();
if(!$.isArray(this.sourceData)) {
return;
}
@ -44,8 +47,11 @@ $(function(){
}))
.append($('<span>').text(' '+this.sourceData[i].text));
$('<div>').append($label).appendTo(this.$input);
$('<div>').append($label).appendTo(this.$tpl);
}
this.$input = this.$tpl.find('input[type="checkbox"]');
this.setClass();
},
value2str: function(value) {
@ -66,10 +72,9 @@ $(function(){
//set checked on required checkboxes
value2input: function(value) {
var $checks = this.$input.find('input[type="checkbox"]');
$checks.removeAttr('checked');
this.$input.removeAttr('checked');
if($.isArray(value) && value.length) {
$checks.each(function(i, el) {
this.$input.each(function(i, el) {
var $el = $(el);
// cannot use $.inArray as it performs strict comparison
$.each(value, function(j, val){
@ -85,7 +90,7 @@ $(function(){
input2value: function() {
var checked = [];
this.$input.find('input:checked').each(function(i, el) {
this.$input.filter(':checked').each(function(i, el) {
checked.push($(el).val());
});
return checked;
@ -94,11 +99,8 @@ $(function(){
//collect text of checked boxes
value2htmlFinal: function(value, element) {
var html = [],
/*jslint eqeq: true*/
checked = $.grep(this.sourceData, function(o){
return $.grep(value, function(v){ return v == o.value; }).length;
});
/*jslint eqeq: false*/
checked = $.fn.editableutils.itemsByValue(value, this.sourceData);
if(checked.length) {
$.each(checked, function(i, v) { html.push($.fn.editableutils.escape(v.text)); });
$(element).html(html.join('<br>'));
@ -108,11 +110,11 @@ $(function(){
},
activate: function() {
this.$input.find('input[type="checkbox"]').first().focus();
this.$input.first().focus();
},
autosubmit: function() {
this.$input.find('input[type="checkbox"]').on('keydown', function(e){
this.$input.on('keydown', function(e){
if (e.which === 13) {
$(this).closest('form').submit();
}
@ -125,21 +127,21 @@ $(function(){
@property tpl
@default <div></div>
**/
tpl:'<div></div>',
tpl:'<div class="editable-checklist"></div>',
/**
@property inputclass
@type string
@default editable-checklist
@default null
**/
inputclass: 'editable-checklist',
inputclass: null,
/**
Separator of values when reading from 'data-value' string
Separator of values when reading from `data-value` attribute
@property separator
@type string
@default ', '
@default ','
**/
separator: ','
});

@ -0,0 +1,185 @@
/**
Combodate input - dropdown date and time picker.
Based on [combodate](http://vitalets.github.com/combodate) plugin. To use it you should manually include [momentjs](http://momentjs.com).
<script src="js/moment.min.js"></script>
Allows to input:
* only date
* only time
* both date and time
Please note, that format is taken from momentjs and **not compatible** with bootstrap-datepicker / jquery UI datepicker.
Internally value stored as `momentjs` object.
@class combodate
@extends abstractinput
@final
@since 1.4.0
@example
<a href="#" id="dob" data-type="combodate" data-pk="1" data-url="/post" data-value="1984-05-15" data-original-title="Select date"></a>
<script>
$(function(){
$('#dob').editable({
format: 'YYYY-MM-DD',
viewformat: 'DD.MM.YYYY',
template: 'D / MMMM / YYYY',
combodate: {
minYear: 2000,
maxYear: 2015,
minuteStep: 1
}
}
});
});
</script>
**/
/*global moment*/
(function ($) {
var Constructor = function (options) {
this.init('combodate', options, Constructor.defaults);
//by default viewformat equals to format
if(!this.options.viewformat) {
this.options.viewformat = this.options.format;
}
//overriding combodate config (as by default jQuery extend() is not recursive)
this.options.combodate = $.extend({}, Constructor.defaults.combodate, options.combodate, {
format: this.options.format,
template: this.options.template
});
};
$.fn.editableutils.inherit(Constructor, $.fn.editabletypes.abstractinput);
$.extend(Constructor.prototype, {
render: function () {
this.$input.combodate(this.options.combodate);
//"clear" link
/*
if(this.options.clear) {
this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function(e){
e.preventDefault();
e.stopPropagation();
this.clear();
}, this));
this.$tpl.parent().append($('<div class="editable-clear">').append(this.$clear));
}
*/
},
value2html: function(value, element) {
var text = value ? value.format(this.options.viewformat) : '';
$(element).text(text);
},
html2value: function(html) {
return html ? moment(html, this.options.viewformat) : null;
},
value2str: function(value) {
return value ? value.format(this.options.format) : '';
},
str2value: function(str) {
return str ? moment(str, this.options.format) : null;
},
value2submit: function(value) {
return this.value2str(value);
},
value2input: function(value) {
this.$input.combodate('setValue', value);
},
input2value: function() {
return this.$input.combodate('getValue', null);
},
activate: function() {
this.$input.siblings('.combodate').find('select').eq(0).focus();
},
/*
clear: function() {
this.$input.data('datepicker').date = null;
this.$input.find('.active').removeClass('active');
},
*/
autosubmit: function() {
}
});
Constructor.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
/**
@property tpl
@default <input type="text">
**/
tpl:'<input type="text">',
/**
@property inputclass
@default null
**/
inputclass: null,
/**
Format used for sending value to server. Also applied when converting date from <code>data-value</code> attribute.<br>
See list of tokens in [momentjs docs](http://momentjs.com/docs/#/parsing/string-format)
@property format
@type string
@default YYYY-MM-DD
**/
format:'YYYY-MM-DD',
/**
Format used for displaying date. Also applied when converting date from element's text on init.
If not specified equals to `format`.
@property viewformat
@type string
@default null
**/
viewformat: null,
/**
Template used for displaying dropdowns.
@property template
@type string
@default D / MMM / YYYY
**/
template: 'D / MMM / YYYY',
/**
Configuration of combodate.
Full list of options: http://vitalets.github.com/combodate/#docs
@property combodate
@type object
@default null
**/
combodate: null
/*
(not implemented yet)
Text shown as clear date button.
If <code>false</code> clear button will not be rendered.
@property clear
@type boolean|string
@default 'x clear'
*/
//clear: '&times; clear'
});
$.fn.editabletypes.combodate = Constructor;
}(window.jQuery));

@ -0,0 +1,398 @@
/**
* Combodate - 1.0.1
* Dropdown date and time picker.
* Converts text input into dropdowns to pick day, month, year, hour, minute and second.
* Uses momentjs as datetime library http://momentjs.com.
* For i18n include corresponding file from https://github.com/timrwood/moment/tree/master/lang
*
* Author: Vitaliy Potapov
* Project page: http://github.com/vitalets/combodate
* Copyright (c) 2012 Vitaliy Potapov. Released under MIT License.
**/
(function ($) {
var Combodate = function (element, options) {
this.$element = $(element);
if(!this.$element.is('input')) {
$.error('Combodate should be applied to INPUT element');
return;
}
this.options = $.extend({}, $.fn.combodate.defaults, options, this.$element.data());
this.init();
};
Combodate.prototype = {
constructor: Combodate,
init: function () {
this.map = {
//key regexp moment.method
day: ['D', 'date'],
month: ['M', 'month'],
year: ['Y', 'year'],
hour: ['[Hh]', 'hours'],
minute: ['m', 'minutes'],
second: ['s', 'seconds'],
ampm: ['[Aa]', '']
};
this.$widget = $('<span class="combodate"></span>').html(this.getTemplate());
this.initCombos();
//update original input on change
this.$widget.on('change', 'select', $.proxy(function(){
this.$element.val(this.getValue());
}, this));
this.$widget.find('select').css('width', 'auto');
//hide original input and insert widget
this.$element.hide().after(this.$widget);
//set initial value
this.setValue(this.$element.val() || this.options.value);
},
/*
Replace tokens in template with <select> elements
*/
getTemplate: function() {
var tpl = this.options.template;
//first pass
$.each(this.map, function(k, v) {
v = v[0];
var r = new RegExp(v+'+'),
token = v.length > 1 ? v.substring(1, 2) : v;
tpl = tpl.replace(r, '{'+token+'}');
});
//replace spaces with &nbsp;
tpl = tpl.replace(/ /g, '&nbsp;');
//second pass
$.each(this.map, function(k, v) {
v = v[0];
var token = v.length > 1 ? v.substring(1, 2) : v;
tpl = tpl.replace('{'+token+'}', '<select class="'+k+'"></select>');
});
return tpl;
},
/*
Initialize combos that presents in template
*/
initCombos: function() {
var that = this;
$.each(this.map, function(k, v) {
var $c = that.$widget.find('.'+k), f, items;
if($c.length) {
that['$'+k] = $c; //set properties like this.$day, this.$month etc.
f = 'fill' + k.charAt(0).toUpperCase() + k.slice(1); //define method name to fill items, e.g `fillDays`
items = that[f]();
that['$'+k].html(that.renderItems(items));
}
});
},
/*
Initialize items of combos. Handles `firstItem` option
*/
initItems: function(key) {
var values = [];
if(this.options.firstItem === 'name') {
var header = typeof moment.relativeTime[key] === 'function' ? moment.relativeTime[key](1, true, key, false) : moment.relativeTime[key];
//take last entry (see momentjs lang files structure)
header = header.split(' ').reverse()[0];
values.push(['', header]);
} else if(this.options.firstItem === 'empty') {
values.push(['', '']);
}
return values;
},
/*
render items to string of <option> tags
*/
renderItems: function(items) {
var str = [];
for(var i=0; i<items.length; i++) {
str.push('<option value="'+items[i][0]+'">'+items[i][1]+'</option>');
}
return str.join("\n");
},
/*
fill day
*/
fillDay: function() {
var items = this.initItems('d'), name, i,
twoDigit = this.options.template.indexOf('DD') !== -1;
for(i=1; i<=31; i++) {
name = twoDigit ? this.leadZero(i) : i;
items.push([i, name]);
}
return items;
},
/*
fill month
*/
fillMonth: function() {
var items = this.initItems('M'), name, i,
longNames = this.options.template.indexOf('MMMM') !== -1,
shortNames = this.options.template.indexOf('MMM') !== -1,
twoDigit = this.options.template.indexOf('MM') !== -1;
for(i=0; i<=11; i++) {
if(longNames) {
name = moment.months[i];
} else if(shortNames) {
name = moment.monthsShort[i];
} else if(twoDigit) {
name = this.leadZero(i+1);
} else {
name = i+1;
}
items.push([i, name]);
}
return items;
},
/*
fill year
*/
fillYear: function() {
var items = this.initItems('y'), name, i,
longNames = this.options.template.indexOf('YYYY') !== -1;
for(i=this.options.maxYear; i>=this.options.minYear; i--) {
name = longNames ? i : (i+'').substring(2);
items.push([i, name]);
}
return items;
},
/*
fill hour
*/
fillHour: function() {
var items = this.initItems('h'), name, i,
h12 = this.options.template.indexOf('h') !== -1,
h24 = this.options.template.indexOf('H') !== -1,
twoDigit = this.options.template.toLowerCase().indexOf('hh') !== -1,
max = h12 ? 12 : 23;
for(i=0; i<=max; i++) {
name = twoDigit ? this.leadZero(i) : i;
items.push([i, name]);
}
return items;
},
/*
fill minute
*/
fillMinute: function() {
var items = this.initItems('m'), name, i,
twoDigit = this.options.template.indexOf('mm') !== -1;
for(i=0; i<=59; i+= this.options.minuteStep) {
name = twoDigit ? this.leadZero(i) : i;
items.push([i, name]);
}
return items;
},
/*
fill second
*/
fillSecond: function() {
var items = this.initItems('s'), name, i,
twoDigit = this.options.template.indexOf('ss') !== -1;
for(i=0; i<=59; i+= this.options.secondStep) {
name = twoDigit ? this.leadZero(i) : i;
items.push([i, name]);
}
return items;
},
/*
fill ampm
*/
fillAmpm: function() {
var ampmL = this.options.template.indexOf('a') !== -1,
ampmU = this.options.template.indexOf('A') !== -1,
items = [
['am', ampmL ? 'am' : 'AM'],
['pm', ampmL ? 'pm' : 'PM']
];
return items;
},
/*
Returns current date value.
If format not specified - `options.format` used.
If format = `null` - Moment object returned.
*/
getValue: function(format) {
var dt, values = {},
that = this,
notSelected = false;
//getting selected values
$.each(this.map, function(k, v) {
if(k === 'ampm') {
return;
}
var def = k === 'day' ? 1 : 0;
values[k] = that['$'+k] ? parseInt(that['$'+k].val(), 10) : def;
if(isNaN(values[k])) {
notSelected = true;
return false;
}
});
//if at least one visible combo not selected - return empty string
if(notSelected) {
return '';
}
//convert hours if 12h format
if(this.$ampm) {
values.hour = this.$ampm.val() === 'am' ? values.hour : values.hour+12;
if(values.hour === 24) {
values.hour = 0;
}
}
dt = moment([values.year, values.month, values.day, values.hour, values.minute, values.second]);
//highlight invalid date
this.highlight(dt);
format = format === undefined ? this.options.format : format;
if(format === null) {
return dt.isValid() ? dt : null;
} else {
return dt.isValid() ? dt.format(format) : '';
}
},
setValue: function(value) {
if(!value) {
return;
}
var dt = typeof value === 'string' ? moment(value, this.options.format) : moment(value),
that = this,
values = {};
if(dt.isValid()) {
//read values from date object
$.each(this.map, function(k, v) {
if(k === 'ampm') {
return;
}
values[k] = dt[v[1]]();
});
if(this.$ampm) {
if(values.hour > 12) {
values.hour -= 12;
values.ampm = 'pm';
} else {
values.ampm = 'am';
}
}
$.each(values, function(k, v) {
if(that['$'+k]) {
that['$'+k].val(v);
}
});
this.$element.val(dt.format(this.options.format));
}
},
/*
highlight combos if date is invalid
*/
highlight: function(dt) {
if(!dt.isValid()) {
if(this.options.errorClass) {
this.$widget.addClass(this.options.errorClass);
} else {
//store original border color
if(!this.borderColor) {
this.borderColor = this.$widget.find('select').css('border-color');
}
this.$widget.find('select').css('border-color', 'red');
}
} else {
if(this.options.errorClass) {
this.$widget.removeClass(this.options.errorClass);
} else {
this.$widget.find('select').css('border-color', this.borderColor);
}
}
},
leadZero: function(v) {
return v <= 9 ? '0' + v : v;
},
destroy: function() {
this.$widget.remove();
this.$element.removeData('combodate').show();
}
//todo: clear method
};
$.fn.combodate = function ( option ) {
var d, args = Array.apply(null, arguments);
args.shift();
//getValue returns date as string / object (not jQuery object)
if(option === 'getValue' && this.length && (d = this.eq(0).data('combodate'))) {
return d.getValue.apply(d, args);
}
return this.each(function () {
var $this = $(this),
data = $this.data('combodate'),
options = typeof option == 'object' && option;
if (!data) {
$this.data('combodate', (data = new Combodate(this, options)));
}
if (typeof option == 'string' && typeof data[option] == 'function') {
data[option].apply(data, args);
}
});
};
$.fn.combodate.defaults = {
//in this format value stored in original input
format: 'DD-MM-YYYY HH:mm',
//in this format items in dropdowns are displayed
template: 'D / MMM / YYYY H : mm',
//initial value, can be `new Date()`
value: null,
minYear: 1970,
maxYear: 2015,
minuteStep: 5,
secondStep: 1,
firstItem: 'empty', //'name', 'empty', 'none'
errorClass: null
};
}(window.jQuery));

File diff suppressed because one or more lines are too long

@ -13,22 +13,26 @@
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
direction: ltr;
/*.dow {
border-top: 1px solid #ddd !important;
}*/
}
}
.datepicker-inline {
width: 220px;
/* height: 220px; */
width: 220px;
}
.datepicker-float {
.datepicker.datepicker-rtl {
direction: rtl;
}
.datepicker.datepicker-rtl table tr td span {
float: right;
}
.datepicker-dropdown {
top: 0;
left: 0;
left: 0;
}
.datepicker-float:before {
.datepicker-dropdown:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
@ -39,7 +43,7 @@
top: -7px;
left: 6px;
}
.datepicker-float:after {
.datepicker-dropdown:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
@ -72,29 +76,31 @@
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
/* vitalets: required to disable css inheritance when display inline inside table */
border: none !important;
background-color: transparent !important;
border: none;
}
.datepicker td.day:hover {
background: #eeeeee !important; /* disable inheritance for inline */
.table-striped .datepicker table tr td,
.table-striped .datepicker table tr th {
background-color: transparent;
}
.datepicker table tr td.day:hover {
background: #eeeeee;
cursor: pointer;
}
.datepicker td.old,
.datepicker td.new {
.datepicker table tr td.old,
.datepicker table tr td.new {
color: #999999;
}
.datepicker td.disabled,
.datepicker td.disabled:hover {
.datepicker table tr td.disabled,
.datepicker table tr td.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker td.today,
.datepicker td.today:hover,
.datepicker td.today.disabled,
.datepicker td.today.disabled:hover {
background-color: #fde19a !important; /* disable inheritance for inline */
.datepicker table tr td.today,
.datepicker table tr td.today:hover,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today.disabled:hover {
background-color: #fde19a;
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
@ -105,116 +111,44 @@
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
border-color: #fdf59a #fdf59a #fbed50;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:dximagetransform.microsoft.gradient(enabled=false);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
}
.datepicker td.today:hover,
.datepicker td.today:hover:hover,
.datepicker td.today.disabled:hover,
.datepicker td.today.disabled:hover:hover,
.datepicker td.today:active,
.datepicker td.today:hover:active,
.datepicker td.today.disabled:active,
.datepicker td.today.disabled:hover:active,
.datepicker td.today.active,
.datepicker td.today:hover.active,
.datepicker td.today.disabled.active,
.datepicker td.today.disabled:hover.active,
.datepicker td.today.disabled,
.datepicker td.today:hover.disabled,
.datepicker td.today.disabled.disabled,
.datepicker td.today.disabled:hover.disabled,
.datepicker td.today[disabled],
.datepicker td.today:hover[disabled],
.datepicker td.today.disabled[disabled],
.datepicker td.today.disabled:hover[disabled] {
background-color: #fdf59a !important; /* disable inheritance for inline */
.datepicker table tr td.today:hover,
.datepicker table tr td.today:hover:hover,
.datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today.disabled:hover:hover,
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today:hover.disabled,
.datepicker table tr td.today.disabled.disabled,
.datepicker table tr td.today.disabled:hover.disabled,
.datepicker table tr td.today[disabled],
.datepicker table tr td.today:hover[disabled],
.datepicker table tr td.today.disabled[disabled],
.datepicker table tr td.today.disabled:hover[disabled] {
background-color: #fdf59a;
}
.datepicker td.today:active,
.datepicker td.today:hover:active,
.datepicker td.today.disabled:active,
.datepicker td.today.disabled:hover:active,
.datepicker td.today.active,
.datepicker td.today:hover.active,
.datepicker td.today.disabled.active,
.datepicker td.today.disabled:hover.active {
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active {
background-color: #fbf069 \9;
}
.datepicker td.active,
.datepicker td.active:hover,
.datepicker td.active.disabled,
.datepicker td.active.disabled:hover {
background-color: #006dcc !important; /* disable inheritance for inline */
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(top, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:dximagetransform.microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker td.active:hover,
.datepicker td.active:hover:hover,
.datepicker td.active.disabled:hover,
.datepicker td.active.disabled:hover:hover,
.datepicker td.active:active,
.datepicker td.active:hover:active,
.datepicker td.active.disabled:active,
.datepicker td.active.disabled:hover:active,
.datepicker td.active.active,
.datepicker td.active:hover.active,
.datepicker td.active.disabled.active,
.datepicker td.active.disabled:hover.active,
.datepicker td.active.disabled,
.datepicker td.active:hover.disabled,
.datepicker td.active.disabled.disabled,
.datepicker td.active.disabled:hover.disabled,
.datepicker td.active[disabled],
.datepicker td.active:hover[disabled],
.datepicker td.active.disabled[disabled],
.datepicker td.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datepicker td.active:active,
.datepicker td.active:hover:active,
.datepicker td.active.disabled:active,
.datepicker td.active.disabled:hover:active,
.datepicker td.active.active,
.datepicker td.active:hover.active,
.datepicker td.active.disabled.active,
.datepicker td.active.disabled:hover.active {
background-color: #003399 \9;
}
.datepicker td span {
display: block;
width: 23%;
height: 54px;
line-height: 54px;
float: left;
margin: 1%;
cursor: pointer;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.datepicker td span:hover {
background: #eeeeee;
}
.datepicker td span.disabled,
.datepicker td span.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker td span.active,
.datepicker td span.active:hover,
.datepicker td span.active.disabled,
.datepicker td span.active.disabled:hover {
.datepicker table tr td.active,
.datepicker table tr td.active:hover,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
@ -226,43 +160,115 @@
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:dximagetransform.microsoft.gradient(enabled=false);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker td span.active:hover,
.datepicker td span.active:hover:hover,
.datepicker td span.active.disabled:hover,
.datepicker td span.active.disabled:hover:hover,
.datepicker td span.active:active,
.datepicker td span.active:hover:active,
.datepicker td span.active.disabled:active,
.datepicker td span.active.disabled:hover:active,
.datepicker td span.active.active,
.datepicker td span.active:hover.active,
.datepicker td span.active.disabled.active,
.datepicker td span.active.disabled:hover.active,
.datepicker td span.active.disabled,
.datepicker td span.active:hover.disabled,
.datepicker td span.active.disabled.disabled,
.datepicker td span.active.disabled:hover.disabled,
.datepicker td span.active[disabled],
.datepicker td span.active:hover[disabled],
.datepicker td span.active.disabled[disabled],
.datepicker td span.active.disabled:hover[disabled] {
.datepicker table tr td.active:hover,
.datepicker table tr td.active:hover:hover,
.datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active.disabled:hover:hover,
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active:hover.disabled,
.datepicker table tr td.active.disabled.disabled,
.datepicker table tr td.active.disabled:hover.disabled,
.datepicker table tr td.active[disabled],
.datepicker table tr td.active:hover[disabled],
.datepicker table tr td.active.disabled[disabled],
.datepicker table tr td.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datepicker td span.active:active,
.datepicker td span.active:hover:active,
.datepicker td span.active.disabled:active,
.datepicker td span.active.disabled:hover:active,
.datepicker td span.active.active,
.datepicker td span.active:hover.active,
.datepicker td span.active.disabled.active,
.datepicker td span.active.disabled:hover.active {
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active {
background-color: #003399 \9;
}
.datepicker td span.old {
.datepicker table tr td span {
display: block;
width: 23%;
height: 54px;
line-height: 54px;
float: left;
margin: 1%;
cursor: pointer;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.datepicker table tr td span:hover {
background: #eeeeee;
}
.datepicker table tr td span.disabled,
.datepicker table tr td span.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td span.active,
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(top, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active:hover:hover,
.datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active.disabled:hover:hover,
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active:hover.disabled,
.datepicker table tr td span.active.disabled.disabled,
.datepicker table tr td span.active.disabled:hover.disabled,
.datepicker table tr td span.active[disabled],
.datepicker table tr td span.active:hover[disabled],
.datepicker table tr td span.active.disabled[disabled],
.datepicker table tr td span.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active {
background-color: #003399 \9;
}
.datepicker table tr td span.old {
color: #999999;
}
.datepicker th.switch {

@ -36,51 +36,45 @@
this.element = $(element);
this.language = options.language||this.element.data('date-language')||"en";
this.language = this.language in dates ? this.language : "en";
this.isRTL = dates[this.language].rtl||false;
this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy');
this.isInline = false;
this.isInline = false;
this.isInput = this.element.is('input');
this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
this.hasInput = this.component && this.element.find('input').length;
if(this.component && this.component.length === 0)
this.component = false;
if (this.isInput) { //single input
this.element.on({
focus: $.proxy(this.show, this),
keyup: $.proxy(this.update, this),
keydown: $.proxy(this.keydown, this)
});
} else if(this.component && this.hasInput) { //component: input + button
// For components that are not readonly, allow keyboard nav
this.element.find('input').on({
focus: $.proxy(this.show, this),
keyup: $.proxy(this.update, this),
keydown: $.proxy(this.keydown, this)
});
this._attachEvents();
this.component.on('click', $.proxy(this.show, this));
} else if(this.element.is('div')) { //inline datepicker
this.isInline = true;
} else {
this.element.on('click', $.proxy(this.show, this));
}
this.forceParse = true;
if ('forceParse' in options) {
this.forceParse = options.forceParse;
} else if ('dateForceParse' in this.element.data()) {
this.forceParse = this.element.data('date-force-parse');
}
this.picker = $(DPGlobal.template)
.appendTo(this.isInline ? this.element : 'body')
.on({
click: $.proxy(this.click, this),
mousedown: $.proxy(this.mousedown, this)
});
if(this.isInline) {
this.picker.addClass('datepicker-inline');
} else {
this.picker.addClass('dropdown-menu');
}
this.picker = $(DPGlobal.template)
.appendTo(this.isInline ? this.element : 'body')
.on({
click: $.proxy(this.click, this),
mousedown: $.proxy(this.mousedown, this)
});
if(this.isInline) {
this.picker.addClass('datepicker-inline');
} else {
this.picker.addClass('datepicker-dropdown dropdown-menu');
}
if (this.isRTL){
this.picker.addClass('datepicker-rtl');
this.picker.find('.prev i, .next i')
.toggleClass('icon-arrow-left icon-arrow-right');
}
$(document).on('mousedown', function (e) {
// Clicked outside the datepicker, hide it
if ($(e.target).closest('.datepicker').length == 0) {
if ($(e.target).closest('.datepicker').length === 0) {
that.hide();
}
});
@ -99,6 +93,7 @@
this.keyboardNavigation = this.element.data('date-keyboard-navigation');
}
this.viewMode = this.startViewMode = 0;
switch(options.startView || this.element.data('date-start-view')){
case 2:
case 'decade':
@ -108,11 +103,6 @@
case 'year':
this.viewMode = this.startViewMode = 1;
break;
case 0:
case 'month':
default:
this.viewMode = this.startViewMode = 0;
break;
}
this.todayBtn = (options.todayBtn||this.element.data('date-today-btn')||false);
@ -122,21 +112,73 @@
this.weekEnd = ((this.weekStart + 6) % 7);
this.startDate = -Infinity;
this.endDate = Infinity;
this.daysOfWeekDisabled = [];
this.setStartDate(options.startDate||this.element.data('date-startdate'));
this.setEndDate(options.endDate||this.element.data('date-enddate'));
this.setDaysOfWeekDisabled(options.daysOfWeekDisabled||this.element.data('date-days-of-week-disabled'));
this.fillDow();
this.fillMonths();
this.update();
this.showMode();
if(this.isInline) {
this.show();
}
if(this.isInline) {
this.show();
}
};
Datepicker.prototype = {
constructor: Datepicker,
_events: [],
_attachEvents: function(){
this._detachEvents();
if (this.isInput) { // single input
this._events = [
[this.element, {
focus: $.proxy(this.show, this),
keyup: $.proxy(this.update, this),
keydown: $.proxy(this.keydown, this)
}]
];
}
else if (this.component && this.hasInput){ // component: input + button
this._events = [
// For components that are not readonly, allow keyboard nav
[this.element.find('input'), {
focus: $.proxy(this.show, this),
keyup: $.proxy(this.update, this),
keydown: $.proxy(this.keydown, this)
}],
[this.component, {
click: $.proxy(this.show, this)
}]
];
}
else if (this.element.is('div')) { // inline datepicker
this.isInline = true;
}
else {
this._events = [
[this.element, {
click: $.proxy(this.show, this)
}]
];
}
for (var i=0, el, ev; i<this._events.length; i++){
el = this._events[i][0];
ev = this._events[i][1];
el.on(ev);
}
},
_detachEvents: function(){
for (var i=0, el, ev; i<this._events.length; i++){
el = this._events[i][0];
ev = this._events[i][1];
el.off(ev);
}
this._events = [];
},
show: function(e) {
this.picker.show();
this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
@ -154,7 +196,7 @@
},
hide: function(e){
if(this.isInline) return;
if(this.isInline) return;
this.picker.hide();
$(window).off('resize', this.place);
this.viewMode = this.startViewMode;
@ -162,7 +204,14 @@
if (!this.isInput) {
$(document).off('mousedown', this.hide);
}
if (e && e.currentTarget.value)
if (
this.forceParse &&
(
this.isInput && this.element.val() ||
this.hasInput && this.element.find('input').val()
)
)
this.setValue();
this.element.trigger({
type: 'hide',
@ -170,9 +219,15 @@
});
},
remove: function() {
this._detachEvents();
this.picker.remove();
delete this.element.data().datepicker;
},
getDate: function() {
var d = this.getUTCDate();
return new Date(d.getTime() + (d.getTimezoneOffset()*60000))
return new Date(d.getTime() + (d.getTimezoneOffset()*60000));
},
getUTCDate: function() {
@ -192,18 +247,19 @@
var formatted = this.getFormattedDate();
if (!this.isInput) {
if (this.component){
this.element.find('input').prop('value', formatted);
this.element.find('input').val(formatted);
}
this.element.data('date', formatted);
} else {
this.element.prop('value', formatted);
this.element.val(formatted);
}
},
getFormattedDate: function(format) {
if(format == undefined) format = this.format;
return DPGlobal.formatDate(this.date, format, this.language);
},
getFormattedDate: function(format) {
if (format === undefined)
format = this.format;
return DPGlobal.formatDate(this.date, format, this.language);
},
setStartDate: function(startDate){
this.startDate = startDate||-Infinity;
@ -223,32 +279,46 @@
this.updateNavArrows();
},
setDaysOfWeekDisabled: function(daysOfWeekDisabled){
this.daysOfWeekDisabled = daysOfWeekDisabled||[];
if (!$.isArray(this.daysOfWeekDisabled)) {
this.daysOfWeekDisabled = this.daysOfWeekDisabled.split(/,\s*/);
}
this.daysOfWeekDisabled = $.map(this.daysOfWeekDisabled, function (d) {
return parseInt(d, 10);
});
this.update();
this.updateNavArrows();
},
place: function(){
if(this.isInline) return;
if(this.isInline) return;
var zIndex = parseInt(this.element.parents().filter(function() {
return $(this).css('z-index') != 'auto';
}).first().css('z-index'))+10;
var offset = this.component ? this.component.offset() : this.element.offset();
var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(true);
this.picker.css({
top: offset.top + this.height,
top: offset.top + height,
left: offset.left,
zIndex: zIndex
});
},
update: function(){
var date, fromArgs = false;
if(arguments && arguments.length && (typeof arguments[0] === 'string' || arguments[0] instanceof Date)) {
date = arguments[0];
fromArgs = true;
} else {
date = this.isInput ? this.element.prop('value') : this.element.data('date') || this.element.find('input').prop('value');
}
var date, fromArgs = false;
if(arguments && arguments.length && (typeof arguments[0] === 'string' || arguments[0] instanceof Date)) {
date = arguments[0];
fromArgs = true;
} else {
date = this.isInput ? this.element.val() : this.element.data('date') || this.element.find('input').val();
}
this.date = DPGlobal.parseDate(date, this.format, this.language);
if(fromArgs) this.setValue();
if(fromArgs) this.setValue();
var oldViewDate = this.viewDate;
if (this.date < this.startDate) {
this.viewDate = new Date(this.startDate);
} else if (this.date > this.endDate) {
@ -256,12 +326,19 @@
} else {
this.viewDate = new Date(this.date);
}
if (oldViewDate && oldViewDate.getTime() != this.viewDate.getTime()){
this.element.trigger({
type: 'changeDate',
date: this.viewDate
});
}
this.fill();
},
fillDow: function(){
var dowCnt = this.weekStart;
var html = '<tr>';
var dowCnt = this.weekStart,
html = '<tr>';
while (dowCnt < this.weekStart + 7) {
html += '<th class="dow">'+dates[this.language].daysMin[(dowCnt++)%7]+'</th>';
}
@ -270,8 +347,8 @@
},
fillMonths: function(){
var html = '';
var i = 0
var html = '',
i = 0;
while (i < 12) {
html += '<span class="month">'+dates[this.language].monthsShort[i++]+'</span>';
}
@ -324,7 +401,8 @@
if (currentDate && prevMonth.valueOf() == currentDate) {
clsName += ' active';
}
if (prevMonth.valueOf() < this.startDate || prevMonth.valueOf() > this.endDate) {
if (prevMonth.valueOf() < this.startDate || prevMonth.valueOf() > this.endDate ||
$.inArray(prevMonth.getUTCDay(), this.daysOfWeekDisabled) !== -1) {
clsName += ' disabled';
}
html.push('<td class="day'+clsName+'">'+prevMonth.getUTCDate() + '</td>');
@ -465,7 +543,7 @@
var year = this.viewDate.getUTCFullYear(),
month = this.viewDate.getUTCMonth();
if (target.is('.old')) {
if (month == 0) {
if (month === 0) {
month = 11;
year -= 1;
} else {
@ -505,8 +583,8 @@
}
if (element) {
element.change();
if (this.autoclose) {
this.hide();
if (this.autoclose && (!which || which == 'date')) {
this.hide();
}
}
},
@ -652,16 +730,16 @@
if (dir) {
this.viewMode = Math.max(0, Math.min(2, this.viewMode + dir));
}
/*
vitalets: fixing bug of very special conditions:
jquery 1.7.1 + webkit + show inline datepicker in bootstrap popover.
Method show() does not set display css correctly and datepicker is not shown.
Changed to .css('display', 'block') solve the problem.
See https://github.com/vitalets/x-editable/issues/37
In jquery 1.7.2+ everything works fine.
*/
//this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
/*
vitalets: fixing bug of very special conditions:
jquery 1.7.1 + webkit + show inline datepicker in bootstrap popover.
Method show() does not set display css correctly and datepicker is not shown.
Changed to .css('display', 'block') solve the problem.
See https://github.com/vitalets/x-editable/issues/37
In jquery 1.7.2+ everything works fine.
*/
//this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).css('display', 'block');
this.updateNavArrows();
}
@ -695,7 +773,7 @@
monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
today: "Today"
}
}
};
var DPGlobal = {
modes: [
@ -715,28 +793,28 @@
navStep: 10
}],
isLeapYear: function (year) {
return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
},
getDaysInMonth: function (year, month) {
return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
},
validParts: /dd?|mm?|MM?|yy(?:yy)?/g,
nonpunctuation: /[^ -\/:-@\[-`{-~\t\n\r]+/g,
validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,
parseFormat: function(format){
// IE treats \0 as a string end in inputs (truncating the value),
// so it's a bad format delimiter, anyway
var separators = format.replace(this.validParts, '\0').split('\0'),
parts = format.match(this.validParts);
if (!separators || !separators.length || !parts || parts.length == 0){
if (!separators || !separators.length || !parts || parts.length === 0){
throw new Error("Invalid date format.");
}
return {separators: separators, parts: parts};
},
parseDate: function(date, format, language) {
if (date instanceof Date) return date;
if (/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(date)) {
var part_re = /([-+]\d+)([dmwy])/,
parts = date.match(/([-+]\d+)([dmwy])/g),
if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)) {
var part_re = /([\-+]\d+)([dmwy])/,
parts = date.match(/([\-+]\d+)([dmwy])/g),
part, dir;
date = new Date();
for (var i=0; i<parts.length; i++) {
@ -781,10 +859,18 @@
setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
setters_map['dd'] = setters_map['d'];
date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
if (parts.length == format.parts.length) {
for (var i=0, cnt = format.parts.length; i < cnt; i++) {
var fparts = format.parts.slice();
// Remove noop parts
if (parts.length != fparts.length) {
fparts = $(fparts).filter(function(i,p){
return $.inArray(p, setters_order) !== -1;
}).toArray();
}
// Process remainder
if (parts.length == fparts.length) {
for (var i=0, cnt = fparts.length; i < cnt; i++) {
val = parseInt(parts[i], 10);
part = format.parts[i];
part = fparts[i];
if (isNaN(val)) {
switch(part) {
case 'MM':
@ -809,8 +895,8 @@
}
for (var i=0, s; i<setters_order.length; i++){
s = setters_order[i];
if (s in parsed)
setters_map[s](date, parsed[s])
if (s in parsed && !isNaN(parsed[s]))
setters_map[s](date, parsed[s]);
}
}
return date;
@ -818,6 +904,8 @@
formatDate: function(date, format, language){
var val = {
d: date.getUTCDate(),
D: dates[language].daysShort[date.getUTCDay()],
DD: dates[language].days[date.getUTCDay()],
m: date.getUTCMonth() + 1,
M: dates[language].monthsShort[date.getUTCMonth()],
MM: dates[language].months[date.getUTCMonth()],
@ -830,7 +918,7 @@
seps = $.extend([], format.separators);
for (var i=0, cnt = format.parts.length; i < cnt; i++) {
if (seps.length)
date.push(seps.shift())
date.push(seps.shift());
date.push(val[format.parts[i]]);
}
return date.join('');
@ -868,7 +956,7 @@
'</table>'+
'</div>'+
'</div>';
$.fn.datepicker.DPGlobal = DPGlobal;
$.fn.datepicker.DPGlobal = DPGlobal;
}( window.jQuery );

@ -1,14 +0,0 @@
/**
* Bulgarian translation for bootstrap-datepicker
* Apostol Apostolov <apostol.s.apostolov@gmail.com>
*/
;(function($){
$.fn.datepicker.dates['bg'] = {
days: ["Неделя", "Понеделник", "Вторник", "Сряда", "Четвъртък", "Петък", "Събота", "Неделя"],
daysShort: ["Нед", "Пон", "Вто", "Сря", "Чет", "Пет", "Съб", "Нед"],
daysMin: ["Н", "П", "В", "С", "Ч", "П", "С", "Н"],
months: ["Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"],
monthsShort: ["Ян", "Фев", "Мар", "Апр", "Май", "Юни", "Юли", "Авг", "Сеп", "Окт", "Ное", "Дек"],
today: "днес"
};
}(jQuery));

@ -1,13 +0,0 @@
/**
* Brazilian translation for bootstrap-datepicker
* Cauan Cabral <cauan@radig.com.br>
*/
;(function($){
$.fn.datepicker.dates['br'] = {
days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado", "Domingo"],
daysShort: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"],
daysMin: ["Do", "Se", "Te", "Qu", "Qu", "Se", "Sa", "Do"],
months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"],
monthsShort: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"]
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Czech translation for bootstrap-datepicker
* Matěj Koubík <matej@koubik.name>
*/
;(function($){
$.fn.datepicker.dates['cs'] = {
days: ["Neděle", "Pondělí", "Úterý", "Středa", "Čtvrtek", "Pátek", "Sobota", "Neděle"],
daysShort: ["Ne", "Po", "Út", "St", "Čt", "Pá", "So", "Ne"],
daysMin: ["N", "P", "Ú", "St", "Č", "P", "So", "N"],
months: ["Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"],
monthsShort: ["Led", "Úno", "Bře", "Dub", "Kvě", "Čer", "Čnc", "Srp", "Zář", "Říj", "Lis", "Pro"],
today: "Dnes"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Danish translation for bootstrap-datepicker
* Christian Pedersen <http://github.com/chripede>
*/
;(function($){
$.fn.datepicker.dates['da'] = {
days: ["Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag", "Søndag"],
daysShort: ["Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør", "Søn"],
daysMin: ["Sø", "Ma", "Ti", "On", "To", "Fr", "Lø", "Sø"],
months: ["Januar", "Februar", "Marts", "April", "Maj", "Juni", "Juli", "August", "September", "Oktober", "November", "December"],
monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"],
today: "I Dag"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* German translation for bootstrap-datepicker
* Sam Zurcher <sam@orelias.ch>
*/
;(function($){
$.fn.datepicker.dates['de'] = {
days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"],
daysShort: ["Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam", "Son"],
daysMin: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"],
months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],
monthsShort: ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"],
today: "Heute"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Spanish translation for bootstrap-datepicker
* Bruno Bonamin <bruno.bonamin@gmail.com>
*/
;(function($){
$.fn.datepicker.dates['es'] = {
days: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo"],
daysShort: ["Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb", "Dom"],
daysMin: ["Do", "Lu", "Ma", "Mi", "Ju", "Vi", "Sa", "Do"],
months: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],
monthsShort: ["Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"],
today: "Hoy"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Finnish translation for bootstrap-datepicker
* Jaakko Salonen <https://github.com/jsalonen>
*/
;(function($){
$.fn.datepicker.dates['fi'] = {
days: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai", "sunnuntai"],
daysShort: ["sun", "maa", "tii", "kes", "tor", "per", "lau", "sun"],
daysMin: ["su", "ma", "ti", "ke", "to", "pe", "la", "su"],
months: ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"],
monthsShort: ["tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mar", "jou"],
today: "tänään"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* French translation for bootstrap-datepicker
* Nico Mollet <nico.mollet@gmail.com>
*/
;(function($){
$.fn.datepicker.dates['fr'] = {
days: ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"],
daysShort: ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"],
daysMin: ["D", "L", "Ma", "Me", "J", "V", "S", "D"],
months: ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"],
monthsShort: ["Jan", "Fev", "Mar", "Avr", "Mai", "Jui", "Jul", "Aou", "Sep", "Oct", "Nov", "Dec"],
today: "Aujourd'hui"
};
}(jQuery));

@ -1,13 +0,0 @@
/**
* Bahasa translation for bootstrap-datepicker
* Azwar Akbar <azwar.akbar@gmail.com>
*/
;(function($){
$.fn.datepicker.dates['id'] = {
days: ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu", "Minggu"],
daysShort: ["Mgu", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab", "Mgu"],
daysMin: ["Mg", "Sn", "Sl", "Ra", "Ka", "Ju", "Sa", "Mg"],
months: ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"],
monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Ags", "Sep", "Okt", "Nov", "Des"]
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Icelandic translation for bootstrap-datepicker
* Hinrik Örn Sigurðsson <hinrik.sig@gmail.com>
*/
;(function($){
$.fn.datepicker.dates['is'] = {
days: ["Sunnudagur", "Mánudagur", "Þriðjudagur", "Miðvikudagur", "Fimmtudagur", "Föstudagur", "Laugardagur", "Sunnudagur"],
daysShort: ["Sun", "Mán", "Þri", "Mið", "Fim", "Fös", "Lau", "Sun"],
daysMin: ["Su", "Má", "Þr", "Mi", "Fi", "Fö", "La", "Su"],
months: ["Janúar", "Febrúar", "Mars", "Apríl", "Maí", "Júní", "Júlí", "Ágúst", "September", "Október", "Nóvember", "Desember"],
monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maí", "Jún", "Júl", "Ágú", "Sep", "Okt", "Nóv", "Des"],
today: "Í Dag"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Italian translation for bootstrap-datepicker
* Enrico Rubboli <rubboli@gmail.com>
*/
;(function($){
$.fn.datepicker.dates['it'] = {
days: ["Domenica", "Lunedi", "Martedi", "Mercoledi", "Giovedi", "Venerdi", "Sabato", "Domenica"],
daysShort: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab", "Dom"],
daysMin: ["Do", "Lu", "Ma", "Me", "Gi", "Ve", "Sa", "Do"],
months: ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"],
monthsShort: ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"],
today: "Oggi"
};
}(jQuery));

@ -1,13 +0,0 @@
/**
* Japanese translation for bootstrap-datepicker
* Norio Suzuki <https://github.com/suzuki/>
*/
;(function($){
$.fn.datepicker.dates['ja'] = {
days: ["日曜", "月曜", "火曜", "水曜", "木曜", "金曜", "土曜", "日曜"],
daysShort: ["日", "月", "火", "水", "木", "金", "土", "日"],
daysMin: ["日", "月", "火", "水", "木", "金", "土", "日"],
months: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
monthsShort: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]
};
}(jQuery));

@ -1,13 +0,0 @@
/**
* Korean translation for bootstrap-datepicker
* Gu Youn <http://github.com/guyoun>
*/
;(function($){
$.fn.datepicker.dates['kr'] = {
days: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일", "일요일"],
daysShort: ["일", "월", "화", "수", "목", "금", "토", "일"],
daysMin: ["일", "월", "화", "수", "목", "금", "토", "일"],
months: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"],
monthsShort: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"],
};
}(jQuery));

@ -1,15 +0,0 @@
/**
* Lithuanian translation for bootstrap-datepicker
* Šarūnas Gliebus <ssharunas@yahoo.co.uk>
*/
;(function($){
$.fn.datepicker.dates['lt'] = {
days: ["Sekmadienis", "Pirmadienis", "Antradienis", "Trečiadienis", "Ketvirtadienis", "Penktadienis", "Šeštadienis", "Sekmadienis"],
daysShort: ["S", "Pr", "A", "T", "K", "Pn", "Š", "S"],
daysMin: ["Sk", "Pr", "An", "Tr", "Ke", "Pn", "Št", "Sk"],
months: ["Sausis", "Vasaris", "Kovas", "Balandis", "Gegužė", "Birželis", "Liepa", "Rugpjūtis", "Rugsėjis", "Spalis", "Lapkritis", "Gruodis"],
monthsShort: ["Sau", "Vas", "Kov", "Bal", "Geg", "Bir", "Lie", "Rugp", "Rugs", "Spa", "Lap", "Gru"],
weekStart: 1
};
}(jQuery));

@ -1,16 +0,0 @@
/**
* Latvian translation for bootstrap-datepicker
* Artis Avotins <artis@apit.lv>
*/
;(function($){
$.fn.datepicker.dates['lv'] = {
days: ["Svētdiena", "Pirmdiena", "Otrdiena", "Trešdiena", "Ceturtdiena", "Piektdiena", "Sestdiena", "Svētdiena"],
daysShort: ["Sv", "P", "O", "T", "C", "Pk", "S", "Sv"],
daysMin: ["Sv", "Pr", "Ot", "Tr", "Ce", "Pk", "St", "Sv"],
months: ["Janvāris", "Februāris", "Marts", "Aprīlis", "Maijs", "Jūnijs", "Jūlijs", "Augusts", "Septembris", "Oktobris", "Novembris", "Decembris"],
monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mai", "Jūn", "Jūl", "Aug", "Sep", "Okt", "Nov", "Dec."],
today: "Šodien",
weekStart: 1
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Malay translation for bootstrap-datepicker
* Ateman Faiz <noorulfaiz@gmail.com>
*/
;(function($){
$.fn.datepicker.dates['ms'] = {
days: ["Ahad", "Isnin", "Selasa", "Rabu", "Khamis", "Jumaat", "Sabtu", "Ahad"],
daysShort: ["Aha", "Isn", "Sel", "Rab", "Kha", "Jum", "Sab", "Aha"],
daysMin: ["Ah", "Is", "Se", "Ra", "Kh", "Ju", "Sa", "Ah"],
months: ["Januari", "Februari", "Mac", "April", "Mei", "Jun", "Julai", "Ogos", "September", "Oktober", "November", "Disember"],
monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Ogo", "Sep", "Okt", "Nov", "Dis"]
today: "Hari Ini"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Norwegian (bokmål) translation for bootstrap-datepicker
* Fredrik Sundmyhr <http://github.com/fsundmyhr>
*/
;(function($){
$.fn.datepicker.dates['nb'] = {
days: ["Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag", "Søndag"],
daysShort: ["Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør", "Søn"],
daysMin: ["Sø", "Ma", "Ti", "On", "To", "Fr", "Lø", "Sø"],
months: ["Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"],
monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Des"],
today: "I Dag"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Dutch translation for bootstrap-datepicker
* Reinier Goltstein <mrgoltstein@gmail.com>
*/
;(function($){
$.fn.datepicker.dates['nl'] = {
days: ["Zondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag", "Zondag"],
daysShort: ["Zo", "Ma", "Di", "Wo", "Do", "Vr", "Za", "Zo"],
daysMin: ["Zo", "Ma", "Di", "Wo", "Do", "Vr", "Za", "Zo"],
months: ["Januari", "Februari", "Maart", "April", "Mei", "Juni", "Juli", "Augustus", "September", "Oktober", "November", "December"],
monthsShort: ["Jan", "Feb", "Mrt", "Apr", "Mei", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"],
today: "Vandaag"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Polish translation for bootstrap-datepicker
* Robert <rtpm@gazeta.pl>
*/
;(function($){
$.fn.datepicker.dates['pl'] = {
days: ["Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota", "Niedziela"],
daysShort: ["Nie", "Pn", "Wt", "Śr", "Czw", "Pt", "So", "Nie"],
daysMin: ["N", "Pn", "Wt", "Śr", "Cz", "Pt", "So", "N"],
months: ["Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"],
monthsShort: ["Sty", "Lu", "Mar", "Kw", "Maj", "Cze", "Lip", "Sie", "Wrz", "Pa", "Lis", "Gru"],
today: "Dzisiaj"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Brazilian translation for bootstrap-datepicker
* Cauan Cabral <cauan@radig.com.br>
*/
;(function($){
$.fn.datepicker.dates['pt-BR'] = {
days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado", "Domingo"],
daysShort: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"],
daysMin: ["Do", "Se", "Te", "Qu", "Qu", "Se", "Sa", "Do"],
months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"],
monthsShort: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"],
today: "Hoje"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Portuguese translation for bootstrap-datepicker
* Original code: Cauan Cabral <cauan@radig.com.br>
* Tiago Melo <tiago.blackcode@gmail.com>
*/
;(function($){
$.fn.datepicker.dates['pt'] = {
days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado", "Domingo"],
daysShort: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"],
daysMin: ["Do", "Se", "Te", "Qu", "Qu", "Se", "Sa", "Do"],
months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"],
monthsShort: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"]
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Russian translation for bootstrap-datepicker
* Victor Taranenko <darwin@snowdale.com>
*/
;(function($){
$.fn.datepicker.dates['ru'] = {
days: ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"],
daysShort: ["Вск", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Суб", "Вск"],
daysMin: ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"],
months: ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"],
monthsShort: ["Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек"],
today: "Сегодня"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Slovene translation for bootstrap-datepicker
* Gregor Rudolf <gregor.rudolf@gmail.com>
*/
;(function($){
$.fn.datepicker.dates['sl'] = {
days: ["Nedelja", "Ponedeljek", "Torek", "Sreda", "Četrtek", "Petek", "Sobota", "Nedelja"],
daysShort: ["Ned", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob", "Ned"],
daysMin: ["Ne", "Po", "To", "Sr", "Če", "Pe", "So", "Ne"],
months: ["Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "November", "December"],
monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Avg", "Sep", "Okt", "Nov", "Dec"],
today: "Danes"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Swedish translation for bootstrap-datepicker
* Patrik Ragnarsson <patrik@starkast.net>
*/
;(function($){
$.fn.datepicker.dates['sv'] = {
days: ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag", "Söndag"],
daysShort: ["Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör", "Sön"],
daysMin: ["Sö", "Må", "Ti", "On", "To", "Fr", "Lö", "Sö"],
months: ["Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"],
monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"],
today: "I Dag"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Thai translation for bootstrap-datepicker
* Suchau Jiraprapot <seroz24@gmail.com>
*/
;(function($){
$.fn.datepicker.dates['th'] = {
days: ["อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัส", "ศุกร์", "เสาร์", "อาทิตย์"],
daysShort: ["อา", "จ", "อ", "พ", "พฤ", "ศ", "ส", "อา"],
daysMin: ["อา", "จ", "อ", "พ", "พฤ", "ศ", "ส", "อา"],
months: ["มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม"],
monthsShort: ["ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค."],
today: "วันนี้"
};
}(jQuery));

@ -1,15 +0,0 @@
/**
* Turkish translation for bootstrap-datepicker
* Serkan Algur <kaisercrazy_2@hotmail.com>
*/
;(function($){
$.fn.datepicker.dates['tr'] = {
days: ["Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi", "Pazar"],
daysShort: ["Pz", "Pzt", "Sal", "Çrş", "Prş", "Cu", "Cts", "Pz"],
daysMin: ["Pz", "Pzt", "Sa", "Çr", "Pr", "Cu", "Ct", "Pz"],
months: ["Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"],
monthsShort: ["Oca", "Şub", "Mar", "Nis", "May", "Haz", "Tem", "Ağu", "Eyl", "Eki", "Kas", "Ara"],
today: "Bugün"
};
}(jQuery));

@ -1,14 +0,0 @@
/**
* Simplified Chinese translation for bootstrap-datepicker
* Yuan Cheung <advanimal@gmail.com>
*/
;(function($){
$.fn.datepicker.dates['zh-CN'] = {
days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"],
daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"],
daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"],
months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
today: "今日"
};
}(jQuery));

@ -1,13 +0,0 @@
/**
* Traditional Chinese translation for bootstrap-datepicker
* Rung-Sheng Jang <daniel@i-trend.co.cc>
*/
;(function($){
$.fn.datepicker.dates['zh-TW'] = {
days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"],
daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"],
daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"],
months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]
};
}(jQuery));

@ -1,7 +1,9 @@
/**
Bootstrap-datepicker.
Description and examples: http://vitalets.github.com/bootstrap-datepicker.
For localization you can include js file from here: https://github.com/eternicode/bootstrap-datepicker/tree/master/js/locales
Description and examples: https://github.com/eternicode/bootstrap-datepicker.
For **i18n** you should include js file from here: https://github.com/eternicode/bootstrap-datepicker/tree/master/js/locales
and set `language` option.
Since 1.4.0 date has different appearance in **popup** and **inline** modes.
@class date
@extends abstractinput
@ -25,45 +27,52 @@ $(function(){
var Date = function (options) {
this.init('date', options, Date.defaults);
//set popular options directly from settings or data-* attributes
var directOptions = $.fn.editableutils.sliceObj(this.options, ['format']);
//overriding datepicker config (as by default jQuery extend() is not recursive)
this.options.datepicker = $.extend({}, Date.defaults.datepicker, directOptions, options.datepicker);
//by default viewformat equals to format
if(!this.options.viewformat) {
this.options.viewformat = this.options.datepicker.format;
}
//language
this.options.datepicker.language = this.options.datepicker.language || 'en';
//store DPglobal
this.dpg = $.fn.datepicker.DPGlobal;
//store parsed formats
this.parsedFormat = this.dpg.parseFormat(this.options.datepicker.format);
this.parsedViewFormat = this.dpg.parseFormat(this.options.viewformat);
this.initPicker(options, Date.defaults);
};
$.fn.editableutils.inherit(Date, $.fn.editabletypes.abstractinput);
$.extend(Date.prototype, {
initPicker: function(options, defaults) {
//'format' is set directly from settings or data-* attributes
//by default viewformat equals to format
if(!this.options.viewformat) {
this.options.viewformat = this.options.format;
}
//overriding datepicker config (as by default jQuery extend() is not recursive)
//since 1.4 datepicker internally uses viewformat instead of format. Format is for submit only
this.options.datepicker = $.extend({}, defaults.datepicker, options.datepicker, {
format: this.options.viewformat
});
//language
this.options.datepicker.language = this.options.datepicker.language || 'en';
//store DPglobal
this.dpg = $.fn.datepicker.DPGlobal;
//store parsed formats
this.parsedFormat = this.dpg.parseFormat(this.options.format);
this.parsedViewFormat = this.dpg.parseFormat(this.options.viewformat);
},
render: function () {
Date.superclass.render.call(this);
this.$input.datepicker(this.options.datepicker);
//"clear" link
if(this.options.clear) {
this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function(e){
e.preventDefault();
e.stopPropagation();
this.clear();
}, this));
}
this.$tpl.parent().append($('<div class="editable-clear">').append(this.$clear));
}
},
value2html: function(value, element) {
var text = value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : '';
Date.superclass.value2html(text, element);
@ -117,12 +126,12 @@ $(function(){
@property tpl
@default <div></div>
**/
tpl:'<div></div>',
tpl:'<div class="editable-date well"></div>',
/**
@property inputclass
@default editable-date well
@default null
**/
inputclass: 'editable-date well',
inputclass: null,
/**
Format used for sending value to server. Also applied when converting date from <code>data-value</code> attribute.<br>
Possible tokens are: <code>d, dd, m, mm, yy, yyyy</code>

@ -0,0 +1,78 @@
/**
Bootstrap datefield input - modification for inline mode.
Shows normal <input type="text"> and binds popup datepicker.
Automatically shown in inline mode.
@class datefield
@extends date
@since 1.4.0
**/
(function ($) {
var DateField = function (options) {
this.init('datefield', options, DateField.defaults);
this.initPicker(options, DateField.defaults);
};
$.fn.editableutils.inherit(DateField, $.fn.editabletypes.date);
$.extend(DateField.prototype, {
render: function () {
this.$input = this.$tpl.find('input');
this.setClass();
this.setAttr('placeholder');
this.$tpl.datepicker(this.options.datepicker);
//need to disable original event handlers
this.$input.off('focus keydown');
//update value of datepicker
this.$input.keyup($.proxy(function(){
this.$tpl.removeData('date');
this.$tpl.datepicker('update');
}, this));
},
value2input: function(value) {
this.$input.val(value ? this.dpg.formatDate(value, this.parsedViewFormat, this.options.datepicker.language) : '');
this.$tpl.datepicker('update');
},
input2value: function() {
return this.html2value(this.$input.val());
},
activate: function() {
$.fn.editabletypes.text.prototype.activate.call(this);
},
autosubmit: function() {
//reset autosubmit to empty
}
});
DateField.defaults = $.extend({}, $.fn.editabletypes.date.defaults, {
/**
@property tpl
**/
tpl:'<div class="input-append date"><input type="text"/><span class="add-on"><i class="icon-th"></i></span></div>',
/**
@property inputclass
@default 'input-small'
**/
inputclass: 'input-small',
/* datepicker config */
datepicker: {
weekStart: 0,
startView: 0,
autoclose: true
}
});
$.fn.editabletypes.datefield = DateField;
}(window.jQuery));

@ -1,7 +1,8 @@
/**
jQuery UI Datepicker.
Description and examples: http://jqueryui.com/datepicker.
This input is also accessible as **date** type. Do not use it together with __bootstrap-datepicker__ as both apply <code>$().datepicker()</code> method.
This input is also accessible as **date** type. Do not use it together with __bootstrap-datepicker__ as both apply <code>$().datepicker()</code> method.
For **i18n** you should include js file from here: https://github.com/jquery/jquery-ui/tree/master/ui/i18n.
@class dateui
@extends abstractinput
@ -25,41 +26,42 @@ $(function(){
var DateUI = function (options) {
this.init('dateui', options, DateUI.defaults);
//set popular options directly from settings or data-* attributes
var directOptions = $.fn.editableutils.sliceObj(this.options, ['format']);
//overriding datepicker config (as by default jQuery extend() is not recursive)
this.options.datepicker = $.extend({}, DateUI.defaults.datepicker, directOptions, options.datepicker);
//by default viewformat equals to format
if(!this.options.viewformat) {
this.options.viewformat = this.options.datepicker.format;
}
//correct formats: replace yyyy with yy
this.options.viewformat = this.options.viewformat.replace('yyyy', 'yy');
this.options.datepicker.format = this.options.datepicker.format.replace('yyyy', 'yy');
//copy format to dateFormat (dateFormat option required for ui datepicker).
//This allows common option 'format' for all datepickers
this.options.datepicker.dateFormat = this.options.datepicker.format;
this.initPicker(options, DateUI.defaults);
};
$.fn.editableutils.inherit(DateUI, $.fn.editabletypes.abstractinput);
$.extend(DateUI.prototype, {
initPicker: function(options, defaults) {
//by default viewformat equals to format
if(!this.options.viewformat) {
this.options.viewformat = this.options.format;
}
//correct formats: replace yyyy with yy (for compatibility with bootstrap datepicker)
this.options.viewformat = this.options.viewformat.replace('yyyy', 'yy');
this.options.format = this.options.format.replace('yyyy', 'yy');
//overriding datepicker config (as by default jQuery extend() is not recursive)
//since 1.4 datepicker internally uses viewformat instead of format. Format is for submit only
this.options.datepicker = $.extend({}, defaults.datepicker, options.datepicker, {
dateFormat: this.options.viewformat
});
},
render: function () {
DateUI.superclass.render.call(this);
this.$input.datepicker(this.options.datepicker);
//"clear" link
if(this.options.clear) {
this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function(e){
e.preventDefault();
e.stopPropagation();
this.clear();
}, this));
}
this.$tpl.parent().append($('<div class="editable-clear">').append(this.$clear));
}
},
value2html: function(value, element) {
@ -82,7 +84,7 @@ $(function(){
},
value2str: function(value) {
return $.datepicker.formatDate(this.options.datepicker.dateFormat, value);
return $.datepicker.formatDate(this.options.format, value);
},
str2value: function(str) {
@ -93,13 +95,13 @@ $(function(){
//if string does not match format, UI datepicker throws exception
var d;
try {
d = $.datepicker.parseDate(this.options.datepicker.dateFormat, str);
d = $.datepicker.parseDate(this.options.format, str);
} catch(e) {}
return d;
},
value2submit: function(value) {
value2submit: function(value) {
return this.value2str(value);
},
@ -134,12 +136,12 @@ $(function(){
@property tpl
@default <div></div>
**/
tpl:'<div></div>',
tpl:'<div class="editable-date"></div>',
/**
@property inputclass
@default 'editable-date'
@default null
**/
inputclass: 'editable-date',
inputclass: null,
/**
Format used for sending value to server. Also applied when converting date from <code>data-value</code> attribute.<br>
Full list of tokens: http://docs.jquery.com/UI/Datepicker/formatDate
@ -174,7 +176,8 @@ $(function(){
datepicker: {
firstDay: 0,
changeYear: true,
changeMonth: true
changeMonth: true,
showOtherMonths: true
},
/**
Text shown as clear date button.
@ -188,6 +191,5 @@ $(function(){
});
$.fn.editabletypes.dateui = DateUI;
$.fn.editabletypes.date = DateUI;
}(window.jQuery));

@ -0,0 +1,77 @@
/**
jQuery UI datefield input - modification for inline mode.
Shows normal <input type="text"> and binds popup datepicker.
Automatically shown in inline mode.
@class dateuifield
@extends dateui
@since 1.4.0
**/
(function ($) {
var DateUIField = function (options) {
this.init('dateuifield', options, DateUIField.defaults);
this.initPicker(options, DateUIField.defaults);
};
$.fn.editableutils.inherit(DateUIField, $.fn.editabletypes.dateui);
$.extend(DateUIField.prototype, {
render: function () {
// this.$input = this.$tpl.find('input');
this.$input.datepicker(this.options.datepicker);
$.fn.editabletypes.text.prototype.renderClear.call(this);
},
value2input: function(value) {
this.$input.val($.datepicker.formatDate(this.options.viewformat, value));
},
input2value: function() {
return this.html2value(this.$input.val());
},
activate: function() {
$.fn.editabletypes.text.prototype.activate.call(this);
},
toggleClear: function() {
$.fn.editabletypes.text.prototype.toggleClear.call(this);
},
autosubmit: function() {
//reset autosubmit to empty
}
});
DateUIField.defaults = $.extend({}, $.fn.editabletypes.dateui.defaults, {
/**
@property tpl
@default <input type="text">
**/
tpl: '<input type="text"/>',
/**
@property inputclass
@default null
**/
inputclass: null,
/* datepicker config */
datepicker: {
showOn: "button",
buttonImage: "http://jqueryui.com/resources/demos/datepicker/images/calendar.gif",
buttonImageOnly: true,
firstDay: 0,
changeYear: true,
changeMonth: true,
showOtherMonths: true
},
/* disable clear link */
clear: false
});
$.fn.editabletypes.dateuifield = DateUIField;
}(window.jQuery));

@ -120,18 +120,9 @@ Number
$.extend(NumberInput.prototype, {
render: function () {
NumberInput.superclass.render.call(this);
if (this.options.min !== null) {
this.$input.attr('min', this.options.min);
}
if (this.options.max !== null) {
this.$input.attr('max', this.options.max);
}
if (this.options.step !== null) {
this.$input.attr('step', this.options.step);
}
this.setAttr('min');
this.setAttr('max');
this.setAttr('step');
}
});
NumberInput.defaults = $.extend({}, $.fn.editabletypes.text.defaults, {
@ -155,29 +146,19 @@ Range (inherit from number)
$.fn.editableutils.inherit(Range, $.fn.editabletypes.number);
$.extend(Range.prototype, {
render: function () {
this.$input = $(this.options.tpl);
var $slider = this.$input.filter('input');
if(this.options.inputclass) {
$slider.addClass(this.options.inputclass);
}
if (this.options.min !== null) {
$slider.attr('min', this.options.min);
}
this.$input = this.$tpl.filter('input');
if (this.options.max !== null) {
$slider.attr('max', this.options.max);
}
this.setClass();
this.setAttr('min');
this.setAttr('max');
this.setAttr('step');
if (this.options.step !== null) {
$slider.attr('step', this.options.step);
}
$slider.on('input', function(){
this.$input.on('input', function(){
$(this).siblings('output').text($(this).val());
});
},
activate: function() {
this.$input.filter('input').focus();
this.$input.focus();
}
});
Range.defaults = $.extend({}, $.fn.editabletypes.number.defaults, {

@ -14,11 +14,9 @@ List - abstract class for inputs that have source option loaded from js array or
$.extend(List.prototype, {
render: function () {
List.superclass.render.call(this);
var deferred = $.Deferred();
this.error = null;
this.sourceData = null;
this.prependData = null;
this.onSourceReady(function () {
this.renderList();
deferred.resolve();
@ -34,20 +32,24 @@ List - abstract class for inputs that have source option loaded from js array or
return null; //can't set value by text
},
value2html: function (value, element, display) {
var deferred = $.Deferred();
this.onSourceReady(function () {
if(typeof display === 'function') {
//custom display method
display.call(element, value, this.sourceData);
} else {
this.value2htmlFinal(value, element);
}
deferred.resolve();
}, function () {
//do nothing with element
deferred.resolve();
});
value2html: function (value, element, display, response) {
var deferred = $.Deferred(),
success = function () {
if(typeof display === 'function') {
//custom display method
display.call(element, value, this.sourceData, response);
} else {
this.value2htmlFinal(value, element);
}
deferred.resolve();
};
//for null value just call success without loading source
if(value === null) {
success.call(this);
} else {
this.onSourceReady(success, function () { deferred.resolve(); });
}
return deferred.promise();
},
@ -73,7 +75,7 @@ List - abstract class for inputs that have source option loaded from js array or
if (typeof this.options.source === 'string') {
//try to get from cache
if(this.options.sourceCache) {
var cacheID = this.options.source + (this.options.name ? '-' + this.options.name : ''),
var cacheID = this.options.source,
cache;
if (!$(document).data(cacheID)) {
@ -84,11 +86,13 @@ List - abstract class for inputs that have source option loaded from js array or
//check for cached data
if (cache.loading === false && cache.sourceData) { //take source from cache
this.sourceData = cache.sourceData;
this.doPrepend();
success.call(this);
return;
} else if (cache.loading === true) { //cache is loading, put callback in stack to be called later
cache.callbacks.push($.proxy(function () {
this.sourceData = cache.sourceData;
this.doPrepend();
success.call(this);
}, this));
@ -107,7 +111,6 @@ List - abstract class for inputs that have source option loaded from js array or
url: this.options.source,
type: 'get',
cache: false,
data: this.options.name ? {name: this.options.name} : {},
dataType: 'json',
success: $.proxy(function (data) {
if(cache) {
@ -115,17 +118,19 @@ List - abstract class for inputs that have source option loaded from js array or
}
this.sourceData = this.makeArray(data);
if($.isArray(this.sourceData)) {
this.doPrepend();
success.call(this);
if(cache) {
//store result in cache
cache.sourceData = this.sourceData;
$.each(cache.callbacks, function () { this.call(); }); //run success callbacks for other fields
//run success callbacks for other fields waiting for this source
$.each(cache.callbacks, function () { this.call(); });
}
this.doPrepend();
success.call(this);
} else {
error.call(this);
if(cache) {
$.each(cache.err_callbacks, function () { this.call(); }); //run error callbacks for other fields
//run error callbacks for other fields waiting for this source
$.each(cache.err_callbacks, function () { this.call(); });
}
}
}, this),
@ -138,8 +143,13 @@ List - abstract class for inputs that have source option loaded from js array or
}
}, this)
});
} else { //options as json/array
this.sourceData = this.makeArray(this.options.source);
} else { //options as json/array/function
if (typeof this.options.source === 'function') {
this.sourceData = this.makeArray(this.options.source());
} else {
this.sourceData = this.makeArray(this.options.source);
}
if($.isArray(this.sourceData)) {
this.doPrepend();
success.call(this);
@ -160,7 +170,11 @@ List - abstract class for inputs that have source option loaded from js array or
if (typeof this.options.prepend === 'string') {
this.options.prepend = {'': this.options.prepend};
}
this.prependData = this.makeArray(this.options.prepend);
if (typeof this.options.prepend === 'function') {
this.prependData = this.makeArray(this.options.prepend());
} else {
this.prependData = this.makeArray(this.options.prepend);
}
}
if($.isArray(this.prependData) && $.isArray(this.sourceData)) {
@ -222,41 +236,41 @@ List - abstract class for inputs that have source option loaded from js array or
return result;
},
//search for item by particular value
itemByVal: function(val) {
if($.isArray(this.sourceData)) {
for(var i=0; i<this.sourceData.length; i++){
/*jshint eqeqeq: false*/
if(this.sourceData[i].value == val) {
/*jshint eqeqeq: true*/
return this.sourceData[i];
}
}
option: function(key, value) {
this.options[key] = value;
if(key === 'source') {
this.sourceData = null;
}
if(key === 'prepend') {
this.prependData = null;
}
}
});
List.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
/**
Source data for list. If string - considered ajax url to load items. Otherwise should be an array.
Array format is: <code>[{value: 1, text: "text"}, {...}]</code><br>
For compability it also supports format <code>{value1: "text1", value2: "text2" ...}</code> but it does not guarantee elements order.
If source is **string**, results will be cached for fields with the same source and name. See also <code>sourceCache</code> option.
Source data for list.
If **array** - it should be in format: `[{value: 1, text: "text1"}, {...}]`
For compability, object format is also supported: `{"1": "text1", "2": "text2" ...}` but it does not guarantee elements order.
If **string** - considered ajax url to load items. In that case results will be cached for fields with the same source and name. See also `sourceCache` option.
If **function**, it should return data in format above (since 1.4.0).
@property source
@type string|array|object
@type string | array | object | function
@default null
**/
source:null,
source: null,
/**
Data automatically prepended to the beginning of dropdown list.
@property prepend
@type string|array|object
@type string | array | object | function
@default false
**/
prepend:false,
prepend: false,
/**
Error message when list cannot be loaded (e.g. ajax error)
@ -279,4 +293,4 @@ List - abstract class for inputs that have source option loaded from js array or
$.fn.editabletypes.list = List;
}(window.jQuery));
}(window.jQuery));

@ -30,6 +30,8 @@ $(function(){
$.extend(Select.prototype, {
renderList: function() {
this.$input.empty();
if(!$.isArray(this.sourceData)) {
return;
}
@ -38,6 +40,8 @@ $(function(){
this.$input.append($('<option>', {value: this.sourceData[i].value}).text(this.sourceData[i].text));
}
this.setClass();
//enter submit
this.$input.on('keydown.editable', function (e) {
if (e.which === 13) {
@ -47,11 +51,14 @@ $(function(){
},
value2htmlFinal: function(value, element) {
var text = '', item = this.itemByVal(value);
if(item) {
text = item.text;
var text = '',
items = $.fn.editableutils.itemsByValue(value, this.sourceData);
if(items.length) {
text = items[0].text;
}
Select.superclass.constructor.superclass.value2html(text, element);
$(element).text(text);
},
autosubmit: function() {

@ -23,11 +23,64 @@ $(function(){
$.fn.editableutils.inherit(Text, $.fn.editabletypes.abstractinput);
$.extend(Text.prototype, {
render: function() {
this.renderClear();
this.setClass();
this.setAttr('placeholder');
},
activate: function() {
if(this.$input.is(':visible')) {
this.$input.focus();
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
if(this.toggleClear) {
this.toggleClear();
}
}
},
//render clear button
renderClear: function() {
if (this.options.clear) {
this.$clear = $('<span class="editable-clear-x"></span>');
this.$input.after(this.$clear)
.css('padding-right', 20)
.keyup($.proxy(this.toggleClear, this))
.parent().css('position', 'relative');
this.$clear.click($.proxy(function(){
this.$clear.hide();
this.$input.val('').focus();
}, this));
}
},
postrender: function() {
if(this.$clear) {
//can position clear button only here, when form is shown and height can be calculated
var h = this.$input.outerHeight() || 20,
delta = (h - this.$clear.height()) / 2;
//workaround for plain-popup
if(delta < 3) {
delta = 3;
}
this.$clear.css({top: delta, right: delta});
}
},
//show / hide clear button
toggleClear: function() {
if(!this.$clear) {
return;
}
if(this.$input.val()) {
this.$clear.show();
} else {
this.$clear.hide();
}
}
});
@ -44,7 +97,16 @@ $(function(){
@type string
@default null
**/
placeholder: null
placeholder: null,
/**
Whether to show `clear` button
@property clear
@type boolean
@default true
**/
clear: true
});
$.fn.editabletypes.text = Text;

@ -10,7 +10,8 @@ Textarea input
$(function(){
$('#comments').editable({
url: '/post',
title: 'Enter comments'
title: 'Enter comments',
rows: 10
});
});
</script>
@ -25,8 +26,10 @@ $(function(){
$.extend(Textarea.prototype, {
render: function () {
Textarea.superclass.render.call(this);
this.setClass();
this.setAttr('placeholder');
this.setAttr('rows');
//ctrl + enter
this.$input.keydown(function (e) {
if (e.ctrlKey && e.which === 13) {
@ -51,42 +54,55 @@ $(function(){
if(!html) {
return '';
}
var regex = new RegExp(String.fromCharCode(10), 'g');
var lines = html.split(/<br\s*\/?>/i);
for (var i = 0; i < lines.length; i++) {
lines[i] = $('<div>').html(lines[i]).text();
var text = $('<div>').html(lines[i]).text();
// Remove newline characters (\n) to avoid them being converted by value2html() method
// thus adding extra <br> tags
text = text.replace(regex, '');
lines[i] = text;
}
return lines.join("\n");
},
return lines.join("\n");
},
activate: function() {
if(this.$input.is(':visible')) {
$.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
this.$input.focus();
}
}
$.fn.editabletypes.text.prototype.activate.call(this);
}
});
Textarea.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
/**
@property tpl
@property tpl
@default <textarea></textarea>
**/
**/
tpl:'<textarea></textarea>',
/**
@property inputclass
@property inputclass
@default input-large
**/
**/
inputclass: 'input-large',
/**
Placeholder attribute of input. Shown when input is empty.
@property placeholder
@property placeholder
@type string
@default null
**/
placeholder: null
**/
placeholder: null,
/**
Number of rows in textarea
@property rows
@type integer
@default 7
**/
rows: 7
});
$.fn.editabletypes.textarea = Textarea;
$.fn.editabletypes.textarea = Textarea;
}(window.jQuery));

@ -20,13 +20,18 @@ define(function () {
init: function(require) {
loadCss(require.toUrl("./editable-container.css"));
}
},
},
//inline container
'containers/editable-inline': ['containers/editable-container'],
'element/editable-element': {
deps: ['require'], //here should be dynamically added container
init: function(require) {
loadCss(require.toUrl("./editable-element.css"));
}
},
//default inputs
'editable-form/editable-form': {
deps: ['require',
'inputs/text',
@ -34,6 +39,7 @@ define(function () {
'inputs/select',
'inputs/checklist',
'inputs/html5types',
'inputs/combodate/combodate',
'inputs-ext/address/address'],
init: function(require) {
loadCss(require.toUrl("./editable-form.css"));
@ -45,9 +51,12 @@ define(function () {
'inputs/text': ['inputs/abstract'],
'inputs/textarea': ['inputs/abstract'],
'inputs/abstract': ['editable-form/editable-form-utils'],
'inputs/html5types': ['inputs/text'],
'inputs/html5types': ['inputs/text'],
'inputs/combodate/combodate': ['inputs/abstract', 'inputs/combodate/lib/combodate', 'inputs/combodate/lib/moment.min'],
//bootstrap
/*
bootstrap
*/
'bootstrap/js/bootstrap': {
deps: ['require'],
init: function(require) {
@ -55,11 +64,12 @@ define(function () {
}
},
'editable-form/editable-form-bootstrap': [
'editable-form/editable-form',
'bootstrap/js/bootstrap'
'editable-form/editable-form',
'bootstrap/js/bootstrap'
],
'containers/editable-popover': ['containers/editable-container',
'bootstrap/js/bootstrap'
'containers/editable-popover': [
'containers/editable-inline',
'bootstrap/js/bootstrap'
],
'inputs/date/date': {
deps: ['require',
@ -71,7 +81,25 @@ define(function () {
}
},
//jqueryui
//wysihtml5
'inputs-ext/wysihtml5/bootstrap-wysihtml5-0.0.2/bootstrap-wysihtml5-0.0.2.min': ['inputs-ext/wysihtml5/bootstrap-wysihtml5-0.0.2/wysihtml5-0.3.0.min'],
'inputs-ext/wysihtml5/wysihtml5': {
deps: ['require',
'bootstrap/js/bootstrap',
'inputs/abstract',
'inputs-ext/wysihtml5/bootstrap-wysihtml5-0.0.2/bootstrap-wysihtml5-0.0.2.min'],
init: function(require) {
loadCss(require.toUrl("./bootstrap-wysihtml5-0.0.2/bootstrap-wysihtml5-0.0.2.css"));
//loadCss(require.toUrl("./bootstrap-wysihtml5-0.0.2/wysiwyg-color.css"));
}
},
//datefield
'inputs/date/datefield': ['inputs/date/date'],
/*
jqueryui
*/
'jqueryui/js/jquery-ui-1.9.1.custom': {
deps: ['require'],
init: function(require) {
@ -79,19 +107,22 @@ define(function () {
}
},
'editable-form/editable-form-jqueryui': [
'editable-form/editable-form',
'jqueryui/js/jquery-ui-1.9.1.custom'
'editable-form/editable-form',
'jqueryui/js/jquery-ui-1.9.1.custom'
],
'containers/editable-tooltip': ['containers/editable-container',
'jqueryui/js/jquery-ui-1.9.1.custom'
'containers/editable-tooltip': [
'containers/editable-inline',
'jqueryui/js/jquery-ui-1.9.1.custom'
],
'inputs/dateui/dateui': ['inputs/abstract'],
'inputs/dateui/dateuifield': ['inputs/dateui/dateui'],
//plain
//'inputs/dateui/dateui': ['inputs/abstract', 'inputs/date/bootstrap-datepicker/js/bootstrap-datepicker'],
/*
plain
*/
'containers/editable-poshytip': [
'containers/editable-container',
'poshytip/jquery.poshytip'
'containers/editable-inline',
'poshytip/jquery.poshytip'
],
'poshytip/jquery.poshytip': {
deps: ['require'],
@ -105,9 +136,7 @@ define(function () {
loadCss(require.toUrl("../css/redmond/jquery-ui-1.9.1.custom.css"));
}
},
//inline container
'containers/editable-inline': ['containers/editable-container'],
//inputs-ext
'inputs-ext/address/address': {
@ -124,19 +153,20 @@ define(function () {
if(f === 'bootstrap') {
//bootstrap
shim['editable-form/editable-form'].deps.push('inputs/date/date');
shim['editable-form/editable-form'].deps.push('inputs/date/datefield');
shim['editable-form/editable-form'].deps.push('inputs-ext/wysihtml5/wysihtml5');
shim['element/editable-element'].deps.push('editable-form/editable-form-bootstrap');
shim['element/editable-element'].deps.push(c === 'popup' ? 'containers/editable-popover' : 'containers/editable-inline');
shim['element/editable-element'].deps.push('containers/editable-popover');
} else if(f === 'jqueryui') {
//jqueryui
shim['editable-form/editable-form'].deps.push('inputs/dateui/dateui');
shim['editable-form/editable-form'].deps.push('inputs/dateui/dateuifield');
shim['element/editable-element'].deps.push('editable-form/editable-form-jqueryui');
shim['element/editable-element'].deps.push(c === 'popup' ? 'containers/editable-tooltip' : 'containers/editable-inline');
shim['element/editable-element'].deps.push('containers/editable-tooltip');
} else {
//plain
shim['editable-form/editable-form'].deps.push('inputs/dateui/dateui');
shim['editable-form/editable-form'].deps.push('inputs/dateui/dateuifield');
shim['inputs/dateui/dateui'].push('inputs/dateui/jquery-ui-datepicker/js/jquery-ui-1.9.1.custom');
shim['element/editable-element'].deps.push(c === 'popup' ? 'containers/editable-poshytip' : 'containers/editable-inline');
shim['element/editable-element'].deps.push('containers/editable-poshytip');
}

@ -19,13 +19,25 @@ require(["loader", jqurl], function(loader) {
function() {
//disable effects
$.fx.off = true;
$.support.transition = false;
$.support.transition = false;
$.fn.editable.defaults.mode = params.c === 'inline' ? 'inline' : 'popup';
QUnit.load();
QUnit.start();
});
function addTests(config) {
var custom;
switch(params.f) {
case 'bootstrap':
custom = ['test/unit/datefield', 'test/unit/date', 'test/unit/wysihtml5'];
break;
default:
custom = ['test/unit/dateuifield', 'test/unit/dateui'];
}
var tests = [
'test/mocks',
'test/unit/common',
@ -33,12 +45,36 @@ require(["loader", jqurl], function(loader) {
'test/unit/textarea',
'test/unit/select',
'test/unit/checklist',
(params.f === 'bootstrap') ? 'test/unit/date' : 'test/unit/dateui',
'test/unit/api'
'test/unit/combodate'
];
tests = tests.concat(custom);
tests.push('test/unit/api');
for(var i=0; i<tests.length-1; i++) {
config.shim[tests[i+1]] = [tests[i]];
}
}
});
});
// implement JSON.stringify serialization for IE7
var JSON = JSON || {};
JSON.stringify = JSON.stringify || function (obj) {
var t = typeof (obj);
if (t != "object" || obj === null) {
// simple data type
if (t == "string") obj = '"'+obj+'"';
return String(obj);
}
else {
// recurse array or object
var n, v, json = [], arr = (obj && obj.constructor == Array);
for (n in obj) {
v = obj[n]; t = typeof(v);
if (t == "string") v = '"'+v+'"';
else if (t == "object" && v !== null) v = JSON.stringify(v);
json.push((arr ? "" : '"' + n + '":') + String(v));
}
return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
}
};

@ -94,7 +94,7 @@ $(function () {
});
e.editable({
source: 'groups.php',
source: 'groups.php'
});
e.click();
@ -103,7 +103,7 @@ $(function () {
var p = tip(e);
test_reason = 'cancel'
p.find('button[type=button]').click(); //cancel
p.find('.editable-cancel').click(); //cancel
ok(!p.is(':visible'), 'popover closed');
test_reason = 'onblur'
@ -147,7 +147,7 @@ $(function () {
});
e.editable({
source: groups,
source: groups
});
e.click();
@ -361,10 +361,40 @@ $(function () {
equal(e.data('editable').value, 1, 'value correct');
equal(e.text(), groups[1], 'text shown correctly');
//open editable to check update of input
e.click();
var p = tip(e);
equal(p.find('select').find('option').length, size, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct');
e.editable('setValue', 2);
equal(e.data('editable').value, 2, 'new value correct');
equal(e.text(), groups[2], 'new text shown correctly');
});
equal(p.find('select').val(), e.data('editable').value, 'new selected value correct');
});
test("`destroy` method", function () {
var e = $('<a href="#" data-name="name" data-type="text" data-url="post.php"></a>').appendTo('#qunit-fixture').editable({
});
e.click();
var p = tip(e);
ok(p.is(':visible'), 'container visible');
e.editable('destroy');
ok(!p.is(':visible'), 'container closed');
ok(!e.data('editable'), 'editable instance removed');
ok(!e.data('editableContainer'), 'editableContainer instance removed');
ok(!e.hasClass('editable'), 'editable class removed');
ok(!e.hasClass('editable-click'), 'editable-click class removed');
e.click();
});
});

@ -17,7 +17,7 @@ $(function () {
value: [2, 3]
});
equal(e.html(), groups[2]+sep+groups[3], 'autotext ok');
equal(e.html().toLowerCase(), (groups[2]+sep+groups[3]).toLowerCase(), 'autotext ok');
$.mockjax({
url: 'post-checklist.php',
@ -47,7 +47,7 @@ $(function () {
ok(!p.is(':visible'), 'popup closed');
equal(e.data('editable').value.join(''), [newValue, 3].join(''), 'new value ok')
equal(e.html(), groups[newValue]+'<br>'+groups[3], 'new text ok');
equal(e.html().toLowerCase(), (groups[newValue]+'<br>'+groups[3]).toLowerCase(), 'new text ok');
// open container again to see what checked
e.click()

107
test/unit/combodate.js Normal file

@ -0,0 +1,107 @@
$(function () {
//formats
var
fd = 'DD.MM.YYYY', vfd = 'DD-MM-YYYY', vd = '15-05-1984',
fdt = 'DD-MM-YYYY hh:mm:ss A', vfdt = 'DD MMM YYYY h:m:s a', vdt = '15-05-1984 08:20:30 PM';
module("combodate", {
setup: function(){
fx = $('#async-fixture');
$.support.transition = false;
}
});
asyncTest("container should contain combodate and save new value (date)", function () {
var e = $('<a href="#" data-type="combodate" data-pk="1" data-url="/combodate">'+vd+'</a>').appendTo(fx).editable({
format: fd,
viewformat: vfd,
template: fd
}),
m = moment(vd, vfd);
$.mockjax({
url: '/combodate',
response: function(settings) {
equal(settings.data.value, m.format(fd), 'submitted value correct');
}
});
equal(e.data('editable').value.format(fd), m.format(fd), 'init value correct');
e.click();
var p = tip(e);
ok(p.find('.combodate').is(':visible'), 'combodate exists');
equal(p.find('.day, .month, .year, .hour, .minute').length, 3, 'combos correct');
equal(p.find('.day').val(), m.date(), 'day set correct');
equal(p.find('.month').val(), m.month(), 'month set correct');
equal(p.find('.year').val(), m.year(), 'year set correct');
//set new day
p.find('.day').val(16).trigger('change');
m.date(16);
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'container closed');
equal(e.data('editable').value.format(fd), m.format(fd), 'new value correct');
equal(e.text(), m.format(vfd), 'new text correct');
e.remove();
start();
}, timeout);
});
asyncTest("container should contain combodate and save new value (datetime)", function () {
var e = $('<a href="#" data-type="combodate" data-pk="1" data-url="/combodate-dt" data-value="'+vdt+'"></a>').appendTo(fx).editable({
format: fdt,
viewformat: vfdt,
template: fdt
}),
m = moment(vdt, fdt);
$.mockjax({
url: '/combodate-dt',
response: function(settings) {
equal(settings.data.value, m.format(fdt), 'submitted value correct');
}
});
equal(e.data('editable').value.format(fdt), m.format(fdt), 'init value correct');
equal(e.text(), m.format(vfdt), 'init text correct');
e.click();
var p = tip(e);
ok(p.find('.combodate').is(':visible'), 'combodate exists');
equal(p.find('.day, .month, .year, .hour, .minute, .second, .ampm').length, 7, 'combos correct');
equal(p.find('.day').val(), m.date(), 'day set correct');
equal(p.find('.month').val(), m.month(), 'month set correct');
equal(p.find('.year').val(), m.year(), 'year set correct');
equal(p.find('.hour').val(), m.hours()-12, 'hour set correct');
equal(p.find('.minute').val(), m.minutes(), 'minute set correct');
equal(p.find('.second').val(), m.seconds(), 'second set correct');
equal(p.find('.ampm').val(), 'pm', 'ampm set correct');
//set new day
p.find('.day').val(16).trigger('change');
p.find('.hour').val(9).trigger('change');
m.date(16);
m.hours(21);
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'container closed');
equal(e.data('editable').value.format(fdt), m.format(fdt), 'new value correct');
equal(e.text(), m.format(vfdt), 'new text correct');
e.remove();
start();
}, timeout);
});
});

@ -64,7 +64,7 @@
test("container's title and placement from json options", function () {
//do not test inline
if($.fn.editableContainer.Constructor.prototype.containerName === 'editableform') {
if($.fn.editable.defaults.mode === 'inline') {
expect(0);
return;
}
@ -81,7 +81,7 @@
ok(p.is(':visible'), 'popover shown');
//todo: for jqueryui phantomjs calcs wrong position. Need investigation
if(!$.browser.webkit && $.fn.editableContainer.Constructor.prototype.containerName !== 'tooltip') {
if(!$.browser.webkit && e.data('editableContainer').containerName !== 'tooltip') {
ok(p.offset().top > e.offset().top, 'placement ok');
}
@ -274,7 +274,14 @@
});
test("should not wrap buttons when parent has position:absolute", function () {
test("should not wrap buttons when parent has position:absolute (except ie7)", function () {
//skip this for: ie7 + bootstrap + popup
if($.browser.msie && parseInt($.browser.version, 10) <= 8 && $.fn.editable.defaults.mode === 'popup' && $.fn.editableContainer.Popup.prototype.containerName === 'popover') {
expect(0);
return;
}
var d = $('<div style="position: absolute; top: 200px">').appendTo(fx),
e = $('<a href="#" data-pk="1" data-url="post.php" data-name="text1">abc</a>').appendTo(d).editable({
showbuttons: true
@ -520,5 +527,23 @@
});
test("mode: popup / inline", function () {
var e = $('<a href="#" id="a"></a>').appendTo('#qunit-fixture').editable({
mode: 'popup'
}),
e1 = $('<a href="#" id="a1"></a>').appendTo('#qunit-fixture').editable({
mode: 'inline'
});
e.click();
var p = tip(e);
ok(p.is(':visible'), 'popup visible');
ok(!p.hasClass('editable-inline'), 'no inline class');
e1.click();
p = tip(e1);
ok(p.is(':visible'), 'inline visible visible');
ok(p.hasClass('editable-inline'), 'has inline class');
});
}(jQuery));

@ -1,13 +1,19 @@
$(function () {
var dpg, f = 'dd.mm.yyyy';
var dpg, f = 'dd.mm.yyyy', mode;
module("date", {
setup: function(){
fx = $('#async-fixture');
dpg = $.fn.datepicker.DPGlobal;
$.support.transition = false;
}
mode = $.fn.editable.defaults.mode;
$.fn.editable.defaults.mode = 'popup';
},
teardown: function() {
//restore mode
$.fn.editable.defaults.mode = mode;
}
});
function frmt(date, format) {
@ -32,30 +38,44 @@ $(function () {
equal(settings.data.value, nextD, 'submitted value correct');
}
});
equal(frmt(e.data('editable').value, 'dd.mm.yyyy'), d, 'value correct');
e.click();
var p = tip(e);
ok(p.find('.datepicker').is(':visible'), 'datepicker exists');
ok(p.find('.datepicker').find('.datepicker-days').is(':visible'), 'datepicker days visible');
equal(frmt(e.data('editable').value, f), d, 'day set correct');
ok(p.find('td.day.active').is(':visible'), 'active day is visible');
equal(p.find('td.day.active').text(), 15, 'day shown correct');
equal(p.find('th.dow').eq(0).text(), 'Mo', 'weekStart correct');
//set new day
p.find('td.day.active').next().click();
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed')
equal(frmt(e.data('editable').value, f), nextD, 'new date saved to value')
equal(e.text(), nextD, 'new text shown')
e.remove();
start();
}, timeout);
//testing func, run twice!
var func = function() {
var df = $.Deferred();
equal(frmt(e.data('editable').value, 'dd.mm.yyyy'), d, 'value correct');
e.click();
var p = tip(e);
ok(p.find('.datepicker').is(':visible'), 'datepicker exists');
equal(p.find('.datepicker').length, 1, 'datepicker single');
ok(p.find('.datepicker').find('.datepicker-days').is(':visible'), 'datepicker days visible');
equal(frmt(e.data('editable').value, f), d, 'day set correct');
ok(p.find('td.day.active').is(':visible'), 'active day is visible');
equal(p.find('td.day.active').text(), 15, 'day shown correct');
equal(p.find('th.dow').eq(0).text(), 'Mo', 'weekStart correct');
//set new day
p.find('td.day.active').next().click();
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed');
equal(frmt(e.data('editable').value, f), nextD, 'new date saved to value');
equal(e.text(), nextD, 'new text shown');
df.resolve();
}, timeout);
return df.promise();
};
$.when(func()).then(function() {
e.editable('setValue', d, true);
$.when(func()).then(function() {
e.remove();
start();
});
});
});
@ -109,10 +129,7 @@ $(function () {
test("viewformat, init by value", function () {
var dview = '15/05/1984',
d = '1984-05-15',
e = $('<a href="#" data-type="date" data-pk="1" data-weekstart="1" data-value="'+d+'"></a>').appendTo('#qunit-fixture').editable({
format: 'yyyy-mm-dd',
viewformat: 'dd/mm/yyyy'
});
e = $('<a href="#" data-type="date" data-pk="1" data-format="yyyy-mm-dd" data-viewformat="dd/mm/yyyy" data-value="'+d+'"></a>').appendTo('#qunit-fixture').editable();
equal(frmt(e.data('editable').value, 'yyyy-mm-dd'), d, 'value correct');
equal(e.text(), dview, 'text correct');
@ -127,7 +144,7 @@ $(function () {
equal(p.find('td.day.active').text(), today.getDate(), 'day shown correct');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover closed');
});

108
test/unit/datefield.js Normal file

@ -0,0 +1,108 @@
$(function () {
var dpg, f = 'dd.mm.yyyy', mode;
module("datefield", {
setup: function(){
fx = $('#async-fixture');
dpg = $.fn.datepicker.DPGlobal;
$.support.transition = false;
mode = $.fn.editable.defaults.mode;
$.fn.editable.defaults.mode = 'inline';
},
teardown: function() {
//restore mode
$.fn.editable.defaults.mode = mode;
}
});
function frmt(date, format) {
return dpg.formatDate(date, dpg.parseFormat(format), 'en');
}
asyncTest("container should contain input with value and save new entered date", function () {
var d = '15.05.1984',
e = $('<a href="#" data-type="date" data-pk="1" data-url="post-datefield.php">'+d+'</a>').appendTo(fx).editable({
format: f,
viewformat: f,
datepicker: {
weekStart: 1
}
}),
nextD = '16.05.1984',
finalD = '17.05.1984';
$.mockjax({
url: 'post-datefield.php',
response: function(settings) {
equal(settings.data.value, finalD, 'submitted value correct');
}
});
equal(frmt(e.data('editable').value, 'dd.mm.yyyy'), d, 'value correct');
e.click();
var p = tip(e);
ok(p.find('input').is(':visible'), 'input exists');
equal(p.find('input').val(), d, 'date set correct');
//open picker
p.find('span').click();
var picker = p.find('span').parent().data().datepicker.picker;
ok(picker.is(':visible'), 'picker shown');
ok(picker.find('td.day.active').is(':visible'), 'active day is visible');
equal(picker.find('td.day.active').text(), 15, 'day shown correct');
equal(picker.find('th.dow').eq(0).text(), 'Mo', 'weekStart correct');
//set new day by picker
picker.find('td.day.active').next().click();
ok(!picker.is(':visible'), 'picker closed');
equal(p.find('input').val(), nextD, 'next day set correct');
p.find('input').val(finalD).trigger('keyup');
equal(picker.find('td.day.active').text(), 17, 'picker active date updated');
//submit
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed');
ok(!picker.is(':visible'), 'picker closed');
equal(frmt(e.data('editable').value, f), finalD, 'new date saved to value');
equal(e.text(), finalD, 'new text shown');
e.remove();
start();
}, timeout);
});
test("viewformat, init by text", function () {
var dview = '15/05/1984',
d = '1984-05-15',
e = $('<a href="#" data-type="date" data-pk="1" data-url="post-date1.php">'+dview+'</a>').appendTo('#qunit-fixture').editable({
format: 'yyyy-mm-dd',
viewformat: 'dd/mm/yyyy'
}),
nextD = '1984-05-16',
nextDview = '16/05/1984';
equal(frmt(e.data('editable').value, 'yyyy-mm-dd'), d, 'value correct');
});
test("viewformat, init by value", function () {
var dview = '15/05/1984',
d = '1984-05-15',
e = $('<a href="#" data-type="date" data-pk="1" data-format="yyyy-mm-dd" data-viewformat="dd/mm/yyyy" data-value="'+d+'"></a>').appendTo('#qunit-fixture').editable();
equal(frmt(e.data('editable').value, 'yyyy-mm-dd'), d, 'value correct');
equal(e.text(), dview, 'text correct');
});
});

@ -1,12 +1,18 @@
$(function () {
var dpg;
var dpg, mode;
module("dateui", {
setup: function(){
fx = $('#async-fixture');
$.support.transition = false;
}
mode = $.fn.editable.defaults.mode;
$.fn.editable.defaults.mode = 'popup';
},
teardown: function() {
//restore mode
$.fn.editable.defaults.mode = mode;
}
});
function frmt(date, format) {
@ -17,7 +23,7 @@ $(function () {
asyncTest("container should contain datepicker with value and save new entered date", function () {
var d = '15.05.1984',
dview = '15/05/1984',
e = $('<a href="#" data-type="date" data-pk="1" data-url="post-date.php">'+dview+'</a>').appendTo(fx).editable({
e = $('<a href="#" data-type="date" data-pk="1" data-url="post-dateui.php">'+dview+'</a>').appendTo(fx).editable({
format: 'dd.mm.yyyy',
viewformat: 'dd/mm/yyyy',
datepicker: {
@ -28,32 +34,47 @@ $(function () {
nextDview = '16/05/1984';
$.mockjax({
url: 'post-date.php',
url: 'post-dateui.php',
response: function(settings) {
equal(settings.data.value, nextD, 'submitted value correct');
}
});
equal(frmt(e.data('editable').value, 'dd.mm.yyyy'), d, 'value correct');
//testing func, run twice!
var func = function() {
var df = $.Deferred();
equal(frmt(e.data('editable').value, 'dd.mm.yyyy'), d, 'value correct');
e.click();
var p = tip(e);
ok(p.find('.ui-datepicker').is(':visible'), 'datepicker exists');
equal(p.find('.ui-datepicker').length, 1, 'datepicker single');
e.click();
var p = tip(e);
ok(p.find('.ui-datepicker').is(':visible'), 'datepicker exists');
equal(p.find('a.ui-state-active').text(), 15, 'day shown correct');
equal(p.find('.ui-datepicker-calendar > thead > tr > th').eq(0).find('span').text(), 'Mo', 'weekStart correct');
equal(p.find('a.ui-state-active').text(), 15, 'day shown correct');
equal(p.find('.ui-datepicker-calendar > thead > tr > th').eq(0).find('span').text(), 'Mo', 'weekStart correct');
//set new day
p.find('a.ui-state-active').parent().next().click();
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed');
equal(frmt(e.data('editable').value, 'dd.mm.yyyy'), nextD, 'new date saved to value');
equal(e.text(), nextDview, 'new text shown');
e.remove();
start();
}, timeout);
//set new day
p.find('a.ui-state-active').parent().next().click();
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed');
equal(frmt(e.data('editable').value, 'dd.mm.yyyy'), nextD, 'new date saved to value');
equal(e.text(), nextDview, 'new text shown');
df.resolve();
}, timeout);
return df.promise();
};
$.when(func()).then(function() {
e.editable('setValue', d, true);
$.when(func()).then(function() {
e.remove();
start();
});
});
});
@ -78,7 +99,7 @@ $(function () {
equal(p.find('a.ui-state-active').text(), today.getDate(), 'day shown correct');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover closed');
});

134
test/unit/dateuifield.js Normal file

@ -0,0 +1,134 @@
$(function () {
var f = 'dd.mm.yyyy', mode;
module("dateuifield", {
setup: function(){
fx = $('#async-fixture');
$.support.transition = false;
mode = $.fn.editable.defaults.mode;
$.fn.editable.defaults.mode = 'inline';
},
teardown: function() {
//restore mode
$.fn.editable.defaults.mode = mode;
}
});
function frmt(date, format) {
format = format.replace('yyyy', 'yy');
return $.datepicker.formatDate(format, date);
}
asyncTest("container should contain input with value and save new entered date", function () {
var d = '15.05.1984',
e = $('<a href="#" data-type="date" data-pk="1" data-url="post-dateuifield.php">'+d+'</a>').appendTo(fx).editable({
format: f,
viewformat: f,
datepicker: {
firstDay: 1
}
}),
nextD = '16.05.1984',
finalD = '17.05.1984';
$.mockjax({
url: 'post-dateuifield.php',
response: function(settings) {
equal(settings.data.value, finalD, 'submitted value correct');
}
});
//testing func, run twice!
var func = function() {
var df = $.Deferred();
equal(frmt(e.data('editable').value, 'dd.mm.yyyy'), d, 'value correct');
e.click();
var p = tip(e);
ok(p.find('input').is(':visible'), 'input exists');
equal(p.find('input').val(), d, 'date set correct');
//open picker
p.find('img').click();
equal(p.find('input').length, 1, 'input is single');
var picker = p.find('input').datepicker('widget');
ok(picker.is(':visible'), 'picker shown');
ok(picker.find('a.ui-state-active').is(':visible'), 'active day is visible');
equal(picker.find('a.ui-state-active').text(), 15, 'day shown correct');
equal(picker.find('.ui-datepicker-calendar > thead > tr > th').eq(0).find('span').text(), 'Mo', 'weekStart correct');
//set new day by picker
picker.find('a.ui-state-active').parent().next().click();
ok(!picker.is(':visible'), 'picker closed');
equal(p.find('input').val(), nextD, 'next day set correct');
p.find('input').val(finalD).trigger('keyup');
equal(picker.find('a.ui-state-active').text(), 17, 'picker active date updated');
//prevent page reload in case of error
p.find('form').submit(function(e){
if(!e.isDefaultPrevented()) {
e.preventDefault();
ok(false, 'form submit not prevented!');
}
})
//submit
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed');
ok(!picker.is(':visible'), 'picker closed');
equal(frmt(e.data('editable').value, f), finalD, 'new date saved to value');
equal(e.text(), finalD, 'new text shown');
df.resolve();
}, timeout);
return df.promise();
};
$.when(func()).then(function() {
e.editable('setValue', d, true);
$.when(func()).then(function() {
e.remove();
start();
});
});
});
test("viewformat, init by text", function () {
var dview = '15/05/1984',
d = '1984-05-15',
e = $('<a href="#" data-type="date" data-pk="1" data-url="post-date1.php">'+dview+'</a>').appendTo('#qunit-fixture').editable({
format: 'yyyy-mm-dd',
viewformat: 'dd/mm/yyyy'
}),
nextD = '1984-05-16',
nextDview = '16/05/1984';
equal(frmt(e.data('editable').value, 'yyyy-mm-dd'), d, 'value correct');
});
test("viewformat, init by value", function () {
var dview = '15/05/1984',
d = '1984-05-15',
e = $('<a href="#" data-type="date" data-pk="1" data-format="yyyy-mm-dd" data-viewformat="dd/mm/yyyy" data-value="'+d+'"></a>').appendTo('#qunit-fixture').editable();
equal(frmt(e.data('editable').value, 'yyyy-mm-dd'), d, 'value correct');
equal(e.text(), dview, 'text correct');
});
});

@ -14,12 +14,15 @@ $(function () {
e.click();
var p = tip(e);
ok(p.find('select').length, 'select exists')
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
})
asyncTest("load options from server", function () {
var e = $('<a href="#" data-type="select" data-name="load-srv" data-value="2" data-source="groups.php">customer</a>').appendTo(fx).editable();
var e = $('<a href="#" data-type="select" data-name="load-srv" data-value="2" data-source="groups.php">customer</a>').appendTo(fx).editable({
//need to disable cache to force request
sourceCache: false
});
e.click();
var p = tip(e);
@ -33,12 +36,20 @@ $(function () {
ok(p.find('select').length, 'select exists');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct') ;
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
//open second time: items should not dublicate
e.click();
ok(p.find('select').length, 'select exists');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct') ;
e.remove();
start();
}, timeout);
})
});
test("load options from json", function () {
var e = $('<a href="#" data-type="select" data-value="2" data-url="post.php">customer</a>').appendTo('#qunit-fixture').editable({
@ -54,7 +65,7 @@ $(function () {
ok(p.find('select').length, 'select exists')
equal(p.find('select').find('option').length, size, 'options loaded')
equal(p.find('select').val(), e.data('editable').value, 'selected value correct')
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
});
@ -72,7 +83,7 @@ $(function () {
equal(p.find('select').find('option').length, groupsArr.length, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
});
@ -90,9 +101,28 @@ $(function () {
ok(p.find('select').length, 'select exists')
equal(p.find('select').find('option').length, arr.length, 'options loaded')
equal(p.find('select').val(), 'x', 'selected value correct')
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
})
});
test("load options from function", function () {
var e = $('<a href="#" data-type="select" data-value="2" data-url="post.php">customer</a>').appendTo('#qunit-fixture').editable({
pk: 1,
prepend: 'prepend',
source: function() {
return groups;
}
});
e.click()
var p = tip(e);
ok(p.is(':visible'), 'popover visible');
ok(p.find('select').length, 'select exists');
equal(p.find('select').find('option').length, size+1, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct') ;
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
});
test("load options from html (single quotes)", function () {
var e = $('<a href="#" data-type="select" data-value="M" data-source=\'{"L":"Low", "": "None", "M": "Medium", "H": "High"}\'>customer</a>').appendTo('#qunit-fixture').editable({
@ -106,7 +136,7 @@ $(function () {
ok(p.find('select').length, 'select exists');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct') ;
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
})
@ -122,7 +152,7 @@ $(function () {
ok(p.find('select').length, 'select exists');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct') ;
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
})
@ -140,7 +170,7 @@ $(function () {
equal(p.find('select').find('option').length, 0, 'options not loaded');
equal(p.find('.editable-error-block').text(), 'error', 'sourceError message shown');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
})
@ -157,7 +187,7 @@ $(function () {
ok(!p.find('select').find('option').length, 'options not loaded')
ok(p.find('button[type=submit]:disabled').length, 'submit-btn disabled')
ok(p.find('.editable-error-block').text().length, 'error shown')
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
start();
@ -246,7 +276,7 @@ $(function () {
asyncTest("cache request for same selects", function () {
//clear cache
$(document).removeData('groups.php-name1');
$(document).removeData('groups.php');
var e = $('<a href="#" data-type="select" data-pk="1" data-name="name1" data-value="2" data-url="post.php" data-source="groups-cache.php">customer</a>').appendTo(fx).editable(),
e1 = $('<a href="#" data-type="select" data-pk="1" id="name1" data-value="2" data-url="post.php" data-source="groups-cache.php">customer</a>').appendTo(fx).editable(),
@ -268,7 +298,7 @@ $(function () {
equal(p.find('select').find('option').length, size, 'options loaded');
equal(req, 1, 'one request performed');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
//click second
@ -280,7 +310,7 @@ $(function () {
equal(p.find('select').find('option').length, size, 'options loaded');
equal(req, 1, 'no extra request, options taken from cache');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
@ -295,7 +325,7 @@ $(function () {
expect(4);
//clear cache
$(document).removeData('groups-cache-sim.php-name1');
$(document).removeData('groups-cache-sim.php');
var req = 0;
$.mockjax({
@ -329,7 +359,7 @@ $(function () {
expect(4);
//clear cache
$(document).removeData('groups-cache-sim-err.php-name1');
$(document).removeData('groups-cache-sim-err.php');
var req = 0;
$.mockjax({
@ -362,50 +392,58 @@ $(function () {
asyncTest("sourceCache: false", function () {
var e = $('<a href="#" data-type="select" data-pk="1" data-name="name1" data-value="2" data-url="post.php" data-source="groups-cache-false.php">customer</a>').appendTo(fx).editable({
sourceCache: false
}),
e1 = $('<a href="#" data-type="select" data-pk="1" id="name1" data-value="2" data-url="post.php" data-source="groups-cache-false.php">customer</a>').appendTo(fx).editable({
sourceCache: false
}),
req = 0;
$.mockjax({
$.mockjax({
url: 'groups-cache-false.php',
response: function() {
req++;
this.responseText = groups;
}
});
//click first
e.click();
var p = tip(e);
});
var req = 0,
e = $('<a href="#" data-type="select" data-pk="1" data-name="name1" data-value="2" data-url="post.php" data-source="groups-cache-false.php"></a>').appendTo(fx).editable({
sourceCache: false
}),
e1 = $('<a href="#" data-type="select" data-pk="1" id="name1" data-value="2" data-url="post.php" data-source="groups-cache-false.php">customer</a>').appendTo(fx).editable({
sourceCache: false
});
setTimeout(function() {
ok(p.is(':visible'), 'popover visible');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(req, 1, 'one request performed');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
//click second
e1.click();
p = tip(e1);
equal(req, 1, 'autotext request performed');
//click first
e.click();
setTimeout(function() {
ok(p.is(':visible'), 'popover2 visible');
var p = tip(e);
ok(p.is(':visible'), 'popover visible');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(req, 2, 'second request performed');
equal(req, 1, 'no additional request performed, loaded on autotext');
p.find('button[type=button]').click();
ok(!p.is(':visible'), 'popover was removed');
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
e1.remove();
start();
}, timeout);
//click second
e1.click();
p = tip(e1);
setTimeout(function() {
ok(p.is(':visible'), 'popover2 visible');
equal(p.find('select').find('option').length, size, 'options loaded');
equal(req, 2, 'second request performed');
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
e1.remove();
start();
}, timeout);
}, timeout);
}, timeout);
});
@ -474,7 +512,7 @@ $(function () {
ok(p.is(':visible'), 'popover visible');
equal(p.find('select').find('option').length, 3, 'options prepended (sync)');
equal(p.find('select').val(), '', 'selected value correct');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
//async
@ -491,7 +529,7 @@ $(function () {
ok(p.is(':visible'), 'popover visible');
equal(p.find('select').find('option').length, size+1, 'options prepended (async)');
equal(p.find('select').val(), 'r', 'selected value correct');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
start();
@ -524,12 +562,19 @@ $(function () {
});
asyncTest("'display' callback", function () {
var e = $('<a href="#" data-type="select" data-value="2" data-url="post.php"></a>').appendTo(fx).editable({
var req = 0,
e = $('<a href="#" data-type="select" data-value="2" data-url="post.php"></a>').appendTo(fx).editable({
pk: 1,
source: groups,
display: function(value, sourceData) {
display: function(value, sourceData, response) {
var els = $.grep(sourceData, function(o) {return o.value == value;});
$(this).text('qq' + els[0].text);
if(req == 0) {
ok(response === undefined, 'response param undefined on first request');
req++;
} else {
ok(response.success, 'response param ok on second request');
}
}
}),
selected = 3;
@ -574,7 +619,76 @@ $(function () {
e.remove();
start();
}, timeout);
})
});
asyncTest("set value to null should not trigger source load", function () {
var req = 0;
$.mockjax({
url: 'groups-null.php',
response: function() {
req++;
}
});
var e = $('<a href="#" data-type="select" data-pk="1" data-name="name1" data-value="1" data-url="post.php" data-source="groups-null.php">11</a>').appendTo(fx).editable(),
d = e.data('editable');
e.editable('setValue', null);
setTimeout(function() {
equal(req, 0, 'no request');
equal(e.text(), d.options.emptytext, 'text correct');
equal(d.value, null, 'value correct');
e.remove();
start();
}, timeout);
});
asyncTest("change source", function () {
var e = $('<a href="#" data-type="select" data-name="load-srv" data-value="2" data-source="groups.php"></a>').appendTo(fx).editable({
//need to disable cache to force request
sourceCache: false
});
setTimeout(function() {
e.click();
var p = tip(e);
equal(p.find('select').find('option').length, size, 'options loaded');
equal(p.find('select').val(), e.data('editable').value, 'selected value correct') ;
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was closed');
$.mockjax({
url: 'groups1.php',
responseText: [{value: 'a', text: 1}, {value: 'b', text: 2}]
});
//set new source
e.editable('option', 'source', 'groups1.php');
e.click();
setTimeout(function() {
p = tip(e);
ok(p.find('select').length, 'select exists');
equal(p.find('select').find('option').length, 2, 'new options loaded');
//disable below test as in ie select.val() return null
// equal(p.find('select').val(), 'a', 'selected value correct') ;
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was closed');
e.remove();
start();
}, timeout);
}, timeout);
});
});

@ -15,8 +15,8 @@ $(function () {
e.click();
var p = tip(e);
equal(p.find('input[type=text]').val(), '', 'input val is empty string')
p.find('button[type=button]').click();
equal(p.find('input[type="text"]').val(), '', 'input val is empty string')
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed')
})
@ -26,7 +26,7 @@ $(function () {
e.click();
var p = tip(e);
equal(p.find('input[type=text]').attr('placeholder'), 'abc', 'placeholder exists');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
});
@ -36,7 +36,7 @@ $(function () {
e.click();
var p = tip(e);
ok(p.find('input[type=text]').hasClass('span4'), 'class set correctly');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
});
@ -86,7 +86,7 @@ $(function () {
});
asyncTest("should show error on server validation", function () {
var msg = 'required',
var msg = "required\nfield",
e = $('<a href="#" data-name="text1">abc</a>').appendTo(fx).editable({
validate: function(value) {
ok(this === e[0], 'scope is ok');
@ -104,8 +104,9 @@ $(function () {
setTimeout(function() {
ok(p.is(':visible'), 'popover still shown');
ok(p.find('.editable-error-block').length, 'class "editable-error-block" exists');
equal(p.find('.editable-error-block').text(), 'required', 'error msg shown');
p.find('button[type=button]').click();
equal(p.find('.editable-error-block').text().toLowerCase(), msg.replace('\n', ''), 'error msg shown');
equal(p.find('.editable-error-block').html().toLowerCase(), msg.replace('\n', '<br>'), 'newline replaced with br');
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
start();
@ -136,7 +137,7 @@ $(function () {
ok(p.is(':visible'), 'popover still shown');
ok(p.find('.error').length, 'class "error" exists');
equal(p.find('.editable-error-block').text(), 'required1', 'error msg shown');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
e = e1;
@ -147,7 +148,7 @@ $(function () {
ok(p.is(':visible'), 'popover still shown');
ok(p.find('.error').length, 'class "error" exists');
equal(p.find('.editable-error-block').text(), 'required2', 'error msg shown');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
});
*/
@ -173,7 +174,7 @@ $(function () {
ok(p.is(':visible'), 'popover still shown');
ok(p.find('.editable-error-block').length, 'class "editable-error-block" exists');
equal(p.find('.editable-error-block').text(), 'error', 'error msg shown');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
start();
@ -203,7 +204,7 @@ $(function () {
equal(e.data('editable').value, 'xyz', 'value ok');
equal(e.text(), 'xyz', 'text ok');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
e.remove();
start();
@ -308,7 +309,7 @@ $(function () {
ok(p.find('.editable-error-block').length, 'class "error" exists')
equal(p.find('.editable-error-block').text(), 'customtext', 'error shown')
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed')
e.remove();
@ -338,7 +339,7 @@ $(function () {
ok(p.find('.error').length, 'class "error" exists')
equal(p.find('.editable-error-block').text(), 'Internal server error', 'error shown')
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed')
e.remove();
@ -394,8 +395,9 @@ $(function () {
asyncTest("'display' callback", function () {
var newText = 'cd<e>;"',
e = $('<a href="#" data-pk="1" data-url="post.php" data-name="text1">abc</a>').appendTo(fx).editable({
display: function(value) {
display: function(value, response) {
ok(this === e[0], 'scope is ok');
ok(response.success, 'response param ok');
$(this).text('qq'+value);
}
});
@ -499,6 +501,32 @@ $(function () {
equal(e.text(), v1, 'new text shown');
}
});
});
test("`clear` option", function () {
var e = $('<a href="#" data-type="text" data-name="text1">abc</a>').appendTo('#qunit-fixture').editable({
clear: true,
send: 'never'
});
e.click()
var p = tip(e);
var c = p.find('.editable-clear-x');
ok(c.is(':visible'), 'clear shown');
p.find('input').val('').trigger('keyup');
ok(!c.is(':visible'), 'clear hidden for empty input');
p.find('input').val('cde').trigger('keyup');
ok(c.is(':visible'), 'clear shown on keyboard input');
c.click();
ok(!c.is(':visible'), 'clear hidden after click');
ok(!p.find('input').val(), 'input empty');
p.find('form').submit();
//reopen with empty
e.click();
ok(!c.is(':visible'), 'clear hidden for empty input');
});
});

@ -16,7 +16,7 @@ $(function () {
var p = tip(e);
ok(p.find('textarea').length, 'textarea exists')
ok(!p.find('textarea').val().length, 'textrea is empty')
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed')
})
@ -25,7 +25,7 @@ $(function () {
e.click()
var p = tip(e);
equal(p.find('textarea').attr('placeholder'), 'abc', 'placeholder exists');
p.find('button[type=button]').click();
p.find('.editable-cancel').click();
ok(!p.is(':visible'), 'popover was removed');
})
@ -58,7 +58,7 @@ $(function () {
})
asyncTest("should replace <br> with newline (on show) and back (on save)", function () {
var v = '12<br>3&lt;i&gt;4<br />56',
var v = '12<br>\n3&lt;i&gt;4<br />56',
e = $('<a href="#" data-type="textarea" data-pk="1" data-url="post.php">'+v+'</a>').appendTo(fx).editable(),
v1 = '12\n3<i>4\n56',
vnew = "12\n3<b>4\n56\n\n78",

77
test/unit/wysihtml5.js Normal file

@ -0,0 +1,77 @@
$(function () {
module("wysihtml5", {
setup: function(){
fx = $('#async-fixture');
$.support.transition = false;
}
});
asyncTest("should load correct value and save new entered value", function () {
//skip test for ie7 as it is not supported by wysihtml5
if($.browser.msie && parseInt($.browser.version, 10) <= 8) {
expect(0);
start();
return;
}
var v1 = '<h1>qq</h1><br>qwerty',
v2 = '11<h2>werqwr</h2>4353',
e = $('<a href="#" data-pk="1" data-url="post.php">'+v1+'</a>').appendTo(fx).editable({
type: 'wysihtml5',
success: function(response, newvalue) {
// construction replace(/\s*\n(?!\r)/g, "") required to clear newlines added in ie8
equal(newvalue.toLowerCase().replace(/\s*\n(?!\r)/g, ""), v2, 'value in success ok');
}
});
//testing func, run twice!
var func = function() {
var df = $.Deferred();
e.click();
setTimeout(function() {
var p = tip(e);
ok(p.is(':visible'), 'container visible');
ok(p.find('textarea').is(':hidden'), 'textarea hidden');
equal(p.find('iframe').length, 1, 'iframe single');
ok(p.find('.wysihtml5-toolbar').length, 'toolbar shown');
var iframe = document.querySelectorAll('.wysihtml5-sandbox'),
$c = $(iframe[0]).contents().find('body');
ok($(iframe[0]).width() > 0, 'iframe has width');
ok($(iframe[0]).height() > 0, 'iframe has height');
equal($c.html().toLowerCase(), v1.toLowerCase(), 'content correct');
//set new value, should wait async while it render to iframe
$c.html(v2);
setTimeout(function() {
p.find('form').submit();
setTimeout(function() {
ok(!p.is(':visible'), 'popover closed');
equal(e.data('editable').value.toLowerCase().replace(/\s*\n(?!\r)/g, ""), v2, 'new text saved to value');
equal(e.html().toLowerCase().replace(/\s*\n(?!\r)/g, ""), v2.toLowerCase(), 'new text shown');
df.resolve();
}, timeout);
}, 500);
}, 500);
return df.promise();
};
$.when(func()).then(function() {
e.editable('setValue', v1, true);
$.when(func()).then(function() {
e.remove();
start();
});
});
});
});