self.menu.moveRel(self.getEl(), self.isRtl() ? [
bindStates: function () {
self.state.on('change:value', function (e) {
if (self.getEl('inp').value !== e.value) {
self.getEl('inp').value = e.value;
self.state.on('change:disabled', function (e) {
self.getEl('inp').disabled = e.value;
self.state.on('change:statusLevel', function (e) {
var statusIconElm = self.getEl('status');
var prefix = self.classPrefix, value = e.value;
funcs.css(statusIconElm, 'display', value === 'none' ? 'none' : '');
funcs.toggleClass(statusIconElm, prefix + 'i-checkmark', value === 'ok');
funcs.toggleClass(statusIconElm, prefix + 'i-warning', value === 'warn');
funcs.toggleClass(statusIconElm, prefix + 'i-error', value === 'error');
self.classes.toggle('has-status', value !== 'none');
funcs.on(self.getEl('status'), 'mouseleave', function () {
self.on('cancel', function (e) {
if (self.menu && self.menu.visible()) {
var focusIdx = function (idx, menu) {
if (menu && menu.items().length > 0) {
menu.items().eq(idx)[0].focus();
self.on('keydown', function (e) {
if (e.target.nodeName === 'INPUT') {
if (keyCode === global$f.DOWN) {
self.fire('autocomplete');
} else if (keyCode === global$f.UP) {
global$7(this.getEl('inp')).off();
var ColorBox = ComboBox.extend({
init: function (settings) {
settings.spellcheck = false;
self.classes.add('colorbox');
self.on('change keyup postrender', function () {
self.repaintColor(self.value());
repaintColor: function (value) {
var openElm = this.getEl('open');
var elm = openElm ? openElm.getElementsByTagName('i')[0] : null;
elm.style.background = value;
bindStates: function () {
self.state.on('change:value', function (e) {
if (self.state.get('rendered')) {
self.repaintColor(e.value);
var PanelButton = Button.extend({
var self = this, settings = self.settings;
self.classes.add('opened');
var panelSettings = settings.panel;
if (panelSettings.type) {
panelSettings.role = panelSettings.role || 'dialog';
panelSettings.popover = true;
panelSettings.autohide = true;
panelSettings.ariaRoot = true;
self.panel = new FloatPanel(panelSettings).on('hide', function () {
self.classes.remove('opened');
}).on('cancel', function (e) {
}).parent(self).renderTo(self.getContainerElm());
var rel = self.panel.testMoveRel(self.getEl(), settings.popoverAlign || (self.isRtl() ? rtlRels : ltrRels));
self.panel.classes.toggle('start', rel.substr(-1) === 'l');
self.panel.classes.toggle('end', rel.substr(-1) === 'r');
var isTop = rel.substr(0, 1) === 't';
self.panel.classes.toggle('bottom', !isTop);
self.panel.classes.toggle('top', isTop);
self.panel.moveRel(self.getEl(), rel);
postRender: function () {
self.aria('haspopup', true);
self.on('click', function (e) {
if (e.control === self) {
if (self.panel && self.panel.visible()) {
self.panel.focus(!!e.aria);
var ColorButton = PanelButton.extend({
init: function (settings) {
this.classes.add('splitbtn');
this.classes.add('colorbutton');
color: function (color) {
this.getEl('preview').style.backgroundColor = color;
resetColor: function () {
this.getEl('preview').style.backgroundColor = null;
renderHtml: function () {
var self = this, id = self._id, prefix = self.classPrefix, text = self.state.get('text');
var icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + self.settings.icon : '';
var image = self.settings.image ? ' style="background-image: url(\'' + self.settings.image + '\')"' : '';
self.classes.add('btn-has-text');
textHtml = '<span class="' + prefix + 'txt">' + self.encode(text) + '</span>';
return '<div id="' + id + '" class="' + self.classes + '" role="button" tabindex="-1" aria-haspopup="true">' + '<button role="presentation" hidefocus="1" type="button" tabindex="-1">' + (icon ? '<i class="' + icon + '"' + image + '></i>' : '') + '<span id="' + id + '-preview" class="' + prefix + 'preview"></span>' + textHtml + '</button>' + '<button type="button" class="' + prefix + 'open" hidefocus="1" tabindex="-1">' + ' <i class="' + prefix + 'caret"></i>' + '</button>' + '</div>';
postRender: function () {
var self = this, onClickHandler = self.settings.onclick;
self.on('click', function (e) {
if (e.aria && e.aria.key === 'down') {
if (e.control === self && !DOM.getParent(e.target, '.' + self.classPrefix + 'open')) {
e.stopImmediatePropagation();
onClickHandler.call(self, e);
delete self.settings.onclick;
var global$g = tinymce.util.Tools.resolve('tinymce.util.Color');
var ColorPicker = Widget.extend({
Defaults: { classes: 'widget colorpicker' },
init: function (settings) {
postRender: function () {
var color = self.color();
var hsv, hueRootElm, huePointElm, svRootElm, svPointElm;
hueRootElm = self.getEl('h');
huePointElm = self.getEl('hp');
svRootElm = self.getEl('sv');
svPointElm = self.getEl('svp');
function getPos(elm, event) {
var pos = funcs.getPos(elm);
x = Math.max(0, Math.min(x / elm.clientWidth, 1));
y = Math.max(0, Math.min(y / elm.clientHeight, 1));
function updateColor(hsv, hueUpdate) {
var hue = (360 - hsv.h) / 360;
funcs.css(huePointElm, { top: hue * 100 + '%' });
svRootElm.style.background = global$g({
function updateSaturationAndValue(e) {
pos = getPos(svRootElm, e);
hsv.v = (1 - pos.y) * 100;
pos = getPos(hueRootElm, e);
hsv.h = (1 - pos.y) * 360;
self._repaint = function () {
self._svdraghelper = new DragHelper(self._id + '-sv', {
start: updateSaturationAndValue,
drag: updateSaturationAndValue
self._hdraghelper = new DragHelper(self._id + '-h', {
return this.color().toRgb();
value: function (value) {
self.color().parse(value);
return self.color().toHex();
this._color = global$g();
renderHtml: function () {
var prefix = self.classPrefix;
var stops = '#ff0000,#ff0080,#ff00ff,#8000ff,#0000ff,#0080ff,#00ffff,#00ff80,#00ff00,#80ff00,#ffff00,#ff8000,#ff0000';
function getOldIeFallbackHtml() {
var i, l, html = '', gradientPrefix, stopsList;
gradientPrefix = 'filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=';
stopsList = stops.split(',');
for (i = 0, l = stopsList.length - 1; i < l; i++) {
html += '<div class="' + prefix + 'colorpicker-h-chunk" style="' + 'height:' + 100 / l + '%;' + gradientPrefix + stopsList[i] + ',endColorstr=' + stopsList[i + 1] + ');' + '-ms-' + gradientPrefix + stopsList[i] + ',endColorstr=' + stopsList[i + 1] + ')' + '"></div>';
var gradientCssText = 'background: -ms-linear-gradient(top,' + stops + ');' + 'background: linear-gradient(to bottom,' + stops + ');';
hueHtml = '<div id="' + id + '-h" class="' + prefix + 'colorpicker-h" style="' + gradientCssText + '">' + getOldIeFallbackHtml() + '<div id="' + id + '-hp" class="' + prefix + 'colorpicker-h-marker"></div>' + '</div>';
return '<div id="' + id + '" class="' + self.classes + '">' + '<div id="' + id + '-sv" class="' + prefix + 'colorpicker-sv">' + '<div class="' + prefix + 'colorpicker-overlay1">' + '<div class="' + prefix + 'colorpicker-overlay2">' + '<div id="' + id + '-svp" class="' + prefix + 'colorpicker-selector1">' + '<div class="' + prefix + 'colorpicker-selector2"></div>' + '</div>' + '</div>' + '</div>' + '</div>' + hueHtml + '</div>';
var DropZone = Widget.extend({
init: function (settings) {
settings = global$4.extend({
text: 'Drop an image here',
self.classes.add('dropzone');
self.classes.add('multiple');
renderHtml: function () {
elm = funcs.create('div', attrs, '<span>' + this.translate(cfg.text) + '</span>');
funcs.css(elm, 'height', cfg.height + 'px');
funcs.css(elm, 'width', cfg.width + 'px');
elm.className = self.classes;
postRender: function () {
var toggleDragClass = function (e) {
self.classes.toggle('dragenter');
self.getEl().className = self.classes;
var filter = function (files) {
var accept = self.settings.accept;
if (typeof accept !== 'string') {
var re = new RegExp('(' + accept.split(/\s*,\s*/).join('|') + ')$', 'i');
return global$4.grep(files, function (file) {
return re.test(file.name);
self.$el.on('dragover', function (e) {
self.$el.on('dragenter', toggleDragClass);
self.$el.on('dragleave', toggleDragClass);
self.$el.on('drop', function (e) {
if (self.state.get('disabled')) {
var files = filter(e.dataTransfer.files);
self.value = function () {
} else if (self.settings.multiple) {
var Path = Widget.extend({
init: function (settings) {
if (!settings.delimiter) {
settings.delimiter = '\xBB';
self.classes.add('path');
self.on('click', function (e) {
if (index = target.getAttribute('data-index')) {
value: self.row()[index],
self.row(self.settings.row);
self.getEl().firstChild.focus();
return this.state.get('row');
this.state.set('row', row);
renderHtml: function () {
return '<div id="' + self._id + '" class="' + self.classes + '">' + self._getDataPathHtml(self.state.get('row')) + '</div>';
bindStates: function () {
self.state.on('change:row', function (e) {
self.innerHtml(self._getDataPathHtml(e.value));
_getDataPathHtml: function (data) {
var prefix = self.classPrefix;
for (i = 0, l = parts.length; i < l; i++) {
html += (i > 0 ? '<div class="' + prefix + 'divider" aria-hidden="true"> ' + self.settings.delimiter + ' </div>' : '') + '<div role="button" class="' + prefix + 'path-item' + (i === l - 1 ? ' ' + prefix + 'last' : '') + '" data-index="' + i + '" tabindex="-1" id="' + self._id + '-' + i + '" aria-level="' + (i + 1) + '">' + parts[i].name + '</div>';
html = '<div class="' + prefix + 'path-item">\xA0</div>';
var ElementPath = Path.extend({
postRender: function () {
var self = this, editor = self.settings.editor;