From f55e639b0298a103a0cf02cbf6986777e639a22f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Paiva?= Date: Thu, 17 Sep 2015 18:36:16 -0300 Subject: [PATCH 1/4] Allow add custom element and custom function --- dist/angular-wysiwyg.js | 1995 +++++++++++++++++------------------ dist/angular-wysiwyg.min.js | 2 +- src/angular-wysiwyg.js | 10 +- 3 files changed, 964 insertions(+), 1043 deletions(-) diff --git a/dist/angular-wysiwyg.js b/dist/angular-wysiwyg.js index 09523f5..4600035 100644 --- a/dist/angular-wysiwyg.js +++ b/dist/angular-wysiwyg.js @@ -23,1051 +23,964 @@ Requires: use compile fuction instead of $compile move button elements to js objects and use doc fragments */ -(function (angular, undefined) { - 'use strict'; - var DEFAULT_MENU = [ - [ - 'bold', - 'italic', - 'underline', - 'strikethrough', - 'subscript', - 'superscript' - ], - ['format-block'], - ['font'], - ['font-size'], - [ - 'font-color', - 'hilite-color' - ], - ['remove-format'], - [ - 'ordered-list', - 'unordered-list', - 'outdent', - 'indent' - ], - [ - 'left-justify', - 'center-justify', - 'right-justify' - ], - [ - 'code', - 'quote', - 'paragraph' - ], - [ - 'link', - 'image' - ] +(function(angular, undefined) { + + 'use strict'; + + var DEFAULT_MENU = [ + ['bold', 'italic', 'underline', 'strikethrough', 'subscript', 'superscript'], + ['format-block'], + ['font'], + ['font-size'], + ['font-color', 'hilite-color'], + ['remove-format'], + ['ordered-list', 'unordered-list', 'outdent', 'indent'], + ['left-justify', 'center-justify', 'right-justify'], + ['code', 'quote', 'paragraph'], + ['link', 'image'] ]; - angular.module('wysiwyg.module', ['colorpicker.module']).directive('wysiwyg', [ - '$timeout', - 'wysiwgGui', - '$compile', - function ($timeout, wysiwgGui, $compile) { - return { - template: '
' + '' + '
' + '
' + '
', - restrict: 'E', - scope: { - value: '=ngModel', - textareaHeight: '@textareaHeight', - textareaName: '@textareaName', - textareaClass: '@textareaClass', - textareaRequired: '@textareaRequired', - textareaId: '@textareaId', - textareaMenu: '=textareaMenu', - textareaCustomMenu: '=textareaCustomMenu', - fn: '&', - disabled: '=?disabledArea' - }, - replace: true, - require: 'ngModel', - link: link, - transclude: true - }; - function link(scope, element, attrs, ngModelController) { - var textarea = element.find('div.wysiwyg-textarea'); - scope.isLink = false; - scope.fontSizes = [ - { - value: '1', - size: '10px' - }, - { - value: '2', - size: '13px' - }, - { - value: '3', - size: '16px' - }, - { - value: '4', - size: '18px' - }, - { - value: '5', - size: '24px' - }, - { - value: '6', - size: '32px' - }, - { - value: '7', - size: '48px' - } - ]; - scope.formatBlocks = [ - { - name: 'Heading Blocks', - value: 'div' - }, - { - name: 'Heading 1', - value: 'h1' - }, - { - name: 'Heading 2', - value: 'h2' - }, - { - name: 'Heading 3', - value: 'h3' - }, - { - name: 'Heading 4', - value: 'h4' - }, - { - name: 'Heading 5', - value: 'h5' - }, - { - name: 'Heading 6', - value: 'h6' - } - ]; - scope.formatBlock = scope.formatBlocks[0]; - scope.fontSize = scope.fontSizes[1]; - if (angular.isArray(scope.cssClasses)) { - scope.cssClasses.unshift('css'); - scope.cssClass = scope.cssClasses[0]; - } - scope.fonts = [ - 'Georgia', - 'Palatino Linotype', - 'Times New Roman', - 'Arial', - 'Helvetica', - 'Arial Black', - 'Comic Sans MS', - 'Impact', - 'Lucida Sans Unicode', - 'Tahoma', - 'Trebuchet MS', - 'Verdana', - 'Courier New', - 'Lucida Console', - 'Helvetica Neue' - ].sort(); - scope.font = scope.fonts[6]; - init(); - function init() { - compileMenu(); - configureDisabledWatch(); - configureBootstrapTitle(); - configureListeners(); - } - function compileMenu() { - wysiwgGui.setCustomElements(scope.textareaCustomMenu); - var menuDiv = element.children('div.wysiwyg-menu')[0]; - menuDiv.appendChild(wysiwgGui.createMenu(scope.textareaMenu)); - $compile(menuDiv)(scope); - } - function configureDisabledWatch() { - scope.$watch('disabled', function (newValue) { - angular.element('div.wysiwyg-menu').find('button').each(function () { - angular.element(this).attr('disabled', newValue); - }); - angular.element('div.wysiwyg-menu').find('select').each(function () { - angular.element(this).attr('disabled', newValue); - }); - }); - } - function configureBootstrapTitle() { - if (attrs.enableBootstrapTitle === 'true' && attrs.enableBootstrapTitle !== undefined) { - element.find('button[title]').tooltip({ container: 'body' }); - } - } - function insertTab(html, position) { - var begining = html.substr(0, position); - var end = html.substr(position); - return begining + ' ' + end; - } - function configureListeners() { - //Send message to calling controller that a button has been clicked. - angular.element('.wysiwyg-menu').find('button').on('click', function () { - var title = angular.element(this); - scope.$emit('wysiwyg.click', title.attr('title') || title.attr('data-original-title')); - }); - textarea.on('input keyup paste mouseup', function () { - var html = textarea.html(); - if (html == '
') { - html = ''; - } - ngModelController.$setViewValue(html); - }); - textarea.on('keydown', function (event) { - if (event.keyCode == 9) { - var TAB_SPACES = 4; - var html = textarea.html(); - var selection = window.getSelection(); - var position = selection.anchorOffset; - event.preventDefault(); // html = insertTab(html, position); - // textarea.html(html); - // selection.collapse(textarea[0].firstChild, position + TAB_SPACES); - } - }); - textarea.on('click keyup focus mouseup', function () { - $timeout(function () { - scope.isBold = scope.cmdState('bold'); - scope.isUnderlined = scope.cmdState('underline'); - scope.isStrikethrough = scope.cmdState('strikethrough'); - scope.isItalic = scope.cmdState('italic'); - scope.isSuperscript = itemIs('SUP'); - //scope.cmdState('superscript'); - scope.isSubscript = itemIs('SUB'); - //scope.cmdState('subscript'); - scope.isRightJustified = scope.cmdState('justifyright'); - scope.isLeftJustified = scope.cmdState('justifyleft'); - scope.isCenterJustified = scope.cmdState('justifycenter'); - scope.isPre = scope.cmdValue('formatblock') === 'pre'; - scope.isBlockquote = scope.cmdValue('formatblock') === 'blockquote'; - scope.isOrderedList = scope.cmdState('insertorderedlist'); - scope.isUnorderedList = scope.cmdState('insertunorderedlist'); - scope.fonts.forEach(function (v, k) { - //works but kinda crappy. - if (scope.cmdValue('fontname').indexOf(v) > -1) { - scope.font = v; - return false; + + angular.module('wysiwyg.module', ['colorpicker.module']) + .directive('wysiwyg', function($timeout, wysiwgGui, $compile) { + return { + template: '
' + + '' + + '
' + + '
' + + '
', + restrict: 'E', + scope: { + value: '=ngModel', + textareaHeight: '@textareaHeight', + textareaName: '@textareaName', + textareaClass: '@textareaClass', + textareaRequired: '@textareaRequired', + textareaId: '@textareaId', + textareaMenu: '=textareaMenu', + textareaCustomMenu: '=textareaCustomMenu', + fn: '&', + disabled: '=?disabled', + textareaCustomFunctions: '=textareaCustomFunctions' + }, + replace: true, + require: 'ngModel', + link: link, + transclude: true + }; + + function link(scope, element, attrs, ngModelController) { + + var textarea = element.find('div.wysiwyg-textarea'); + + scope.isLink = false; + + scope.fontSizes = [{ + value: '1', + size: '10px' + }, { + value: '2', + size: '13px' + }, { + value: '3', + size: '16px' + }, { + value: '4', + size: '18px' + }, { + value: '5', + size: '24px' + }, { + value: '6', + size: '32px' + }, { + value: '7', + size: '48px' + }]; + + scope.formatBlocks = [{ + name: 'Heading Blocks', + value: 'div' + }, { + name: 'Heading 1', + value: 'h1' + }, { + name: 'Heading 2', + value: 'h2' + }, { + name: 'Heading 3', + value: 'h3' + }, { + name: 'Heading 4', + value: 'h4' + }, { + name: 'Heading 5', + value: 'h5' + }, { + name: 'Heading 6', + value: 'h6' + }, ]; + scope.formatBlock = scope.formatBlocks[0]; + + scope.fontSize = scope.fontSizes[1]; + + if (angular.isArray(scope.cssClasses)) { + scope.cssClasses.unshift('css'); + scope.cssClass = scope.cssClasses[0]; } - }); - scope.cmdValue('formatblock').toLowerCase(); - scope.formatBlocks.forEach(function (v, k) { - if (scope.cmdValue('formatblock').toLowerCase() === v.value.toLowerCase()) { - scope.formatBlock = v; - return false; + + scope.fonts = [ + 'Georgia', + 'Palatino Linotype', + 'Times New Roman', + 'Arial', + 'Helvetica', + 'Arial Black', + 'Comic Sans MS', + 'Impact', + 'Lucida Sans Unicode', + 'Tahoma', + 'Trebuchet MS', + 'Verdana', + 'Courier New', + 'Lucida Console', + 'Helvetica Neue' + ].sort(); + + scope.font = scope.fonts[6]; + + init(); + + function init() { + + compileMenu(); + configureDisabledWatch(); + configureBootstrapTitle(); + configureListeners(); } - }); - scope.fontSizes.forEach(function (v, k) { - if (scope.cmdValue('fontsize') === v.value) { - scope.fontSize = v; - return false; + + function compileMenu() { + wysiwgGui.setCustomElements(scope.textareaCustomMenu); + var menuDiv = element.children('div.wysiwyg-menu')[0]; + menuDiv.appendChild(wysiwgGui.createMenu(scope.textareaMenu)); + $compile(menuDiv)(scope); } - }); - scope.hiliteColor = getHiliteColor(); - element.find('button.wysiwyg-hiliteColor').css('background-color', scope.hiliteColor); - scope.fontColor = scope.cmdValue('forecolor'); - element.find('button.wysiwyg-fontcolor').css('color', scope.fontColor); - scope.isLink = itemIs('A'); - }, 0); - }); - } - //Used to detect things like A tags and others that dont work with cmdValue(). - function itemIs(tag) { - var selection = window.getSelection().getRangeAt(0); - if (selection) { - if (selection.startContainer.parentNode.tagName === tag.toUpperCase() || selection.endContainer.parentNode.tagName === tag.toUpperCase()) { - return true; - } else { - return false; - } - } else { - return false; - } - } - //Used to detect things like A tags and others that dont work with cmdValue(). - function getHiliteColor() { - var selection = window.getSelection().getRangeAt(0); - if (selection) { - var style = angular.element(selection.startContainer.parentNode).attr('style'); - if (!angular.isDefined(style)) - return false; - var a = style.split(';'); - for (var i = 0; i < a.length; i++) { - var s = a[i].split(':'); - if (s[0] === 'background-color') - return s[1]; - } - return '#fff'; - } else { - return '#fff'; - } - } - // model -> view - ngModelController.$render = function () { - textarea.html(ngModelController.$viewValue); - }; - scope.format = function (cmd, arg) { - document.execCommand(cmd, false, arg); - }; - scope.cmdState = function (cmd) { - return document.queryCommandState(cmd); - }; - scope.cmdValue = function (cmd) { - return document.queryCommandValue(cmd); - }; - scope.createLink = function () { - var input = prompt('Enter the link URL'); - if (input && input !== undefined) - scope.format('createlink', input); - }; - scope.insertImage = function () { - var input = prompt('Enter the image URL'); - if (input && input !== undefined) - scope.format('insertimage', input); - }; - scope.setFont = function () { - scope.format('fontname', scope.font); - }; - scope.setFontSize = function () { - scope.format('fontsize', scope.fontSize.value); - }; - scope.setFormatBlock = function () { - scope.format('formatBlock', scope.formatBlock.value); - }; - scope.setFontColor = function () { - scope.format('forecolor', scope.fontColor); - }; - scope.setHiliteColor = function () { - scope.format('hiliteColor', scope.hiliteColor); - }; - scope.format('enableobjectresizing', true); - scope.format('styleWithCSS', true); - } - } - ]).factory('wysiwgGui', [ - 'wysiwgGuiElements', - function (wysiwgGuiElements) { - var ELEMENTS = wysiwgGuiElements; - var custom = {}; - var setCustomElements = function (el) { - custom = el; - }; - var getMenuGroup = function () { - return { - tag: 'div', - classes: 'btn-group btn-group-sm wysiwyg-btn-group-margin' - }; - }; - var getMenuItem = function (item) { - return ELEMENTS[item] || {}; - }; - var createMenu = function (menu) { - angular.extend(ELEMENTS, custom); - //Get the default menu or the passed in menu - if (angular.isDefined(menu) && menu !== '') { - menu = menu; //stringToArray(menu) - } else { - menu = DEFAULT_MENU; - } - //create div to add everything to. - var startDiv = document.createElement('div'); - var el; - for (var i = 0; i < menu.length; i++) { - var menuGroup = create(getMenuGroup()); - for (var j = 0; j < menu[i].length; j++) { - //link has two functions link and unlink - if (menu[i][j] === 'link') { - el = create(getMenuItem('unlink')); - menuGroup.appendChild(el); + + function configureDisabledWatch() { + scope.$watch('disabled', function(newValue) { + angular.element('div.wysiwyg-menu').find('button').each(function() { + angular.element(this).attr('disabled', newValue); + }); + angular.element('div.wysiwyg-menu').find('select').each(function() { + angular.element(this).attr('disabled', newValue); + }); + }); + } + + function configureBootstrapTitle() { + if (attrs.enableBootstrapTitle === 'true' && attrs.enableBootstrapTitle !== undefined) { + element.find('button[title]').tooltip({ + container: 'body' + }); + } + } + + function insertTab(html, position) { + var begining = html.substr(0, position); + var end = html.substr(position); + return begining + ' ' + end; + } + + function configureListeners() { + + //Send message to calling controller that a button has been clicked. + angular.element('.wysiwyg-menu').find('button').on('click', function() { + var title = angular.element(this); + scope.$emit('wysiwyg.click', title.attr('title') || title.attr('data-original-title')); + }); + + textarea.on('input keyup paste mouseup', function() { + var html = textarea.html(); + + if (html == '
') { + html = ''; + } + + ngModelController.$setViewValue(html); + }); + + textarea.on('keydown', function(event) { + if (event.keyCode == 9) { + var TAB_SPACES = 4; + var html = textarea.html(); + var selection = window.getSelection(); + var position = selection.anchorOffset; + + event.preventDefault(); + // html = insertTab(html, position); + // textarea.html(html); + // selection.collapse(textarea[0].firstChild, position + TAB_SPACES); + } + }); + + textarea.on('click keyup focus mouseup', function() { + $timeout(function() { + scope.isBold = scope.cmdState('bold'); + scope.isUnderlined = scope.cmdState('underline'); + scope.isStrikethrough = scope.cmdState('strikethrough'); + scope.isItalic = scope.cmdState('italic'); + scope.isSuperscript = itemIs('SUP'); //scope.cmdState('superscript'); + scope.isSubscript = itemIs('SUB'); //scope.cmdState('subscript'); + scope.isRightJustified = scope.cmdState('justifyright'); + scope.isLeftJustified = scope.cmdState('justifyleft'); + scope.isCenterJustified = scope.cmdState('justifycenter'); + scope.isPre = scope.cmdValue('formatblock') === 'pre'; + scope.isBlockquote = scope.cmdValue('formatblock') === 'blockquote'; + + scope.isOrderedList = scope.cmdState('insertorderedlist'); + scope.isUnorderedList = scope.cmdState('insertunorderedlist'); + + scope.fonts.forEach(function(v, k) { //works but kinda crappy. + if (scope.cmdValue('fontname').indexOf(v) > -1) { + scope.font = v; + return false; + } + }); + scope.cmdValue('formatblock').toLowerCase(); + scope.formatBlocks.forEach(function(v, k) { + if (scope.cmdValue('formatblock').toLowerCase() === v.value.toLowerCase()) { + scope.formatBlock = v; + return false; + } + }); + + scope.fontSizes.forEach(function(v, k) { + if (scope.cmdValue('fontsize') === v.value) { + scope.fontSize = v; + return false; + } + }); + + scope.hiliteColor = getHiliteColor(); + element.find('button.wysiwyg-hiliteColor').css('background-color', scope.hiliteColor); + + scope.fontColor = scope.cmdValue('forecolor'); + element.find('button.wysiwyg-fontcolor').css('color', scope.fontColor); + + scope.isLink = itemIs('A'); + + }, 0); + }); + } + + //Used to detect things like A tags and others that dont work with cmdValue(). + function itemIs(tag) { + var selection = window.getSelection().getRangeAt(0); + if (selection) { + if (selection.startContainer.parentNode.tagName === tag.toUpperCase() || selection.endContainer.parentNode.tagName === tag.toUpperCase()) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + //Used to detect things like A tags and others that dont work with cmdValue(). + function getHiliteColor() { + var selection = window.getSelection().getRangeAt(0); + if (selection) { + var style = angular.element(selection.startContainer.parentNode).attr('style'); + + if (!angular.isDefined(style)) + return false; + + var a = style.split(';'); + for (var i = 0; i < a.length; i++) { + var s = a[i].split(':'); + if (s[0] === 'background-color') + return s[1]; + } + return '#fff'; + } else { + return '#fff'; + } + } + + // model -> view + ngModelController.$render = function() { + textarea.html(ngModelController.$viewValue); + }; + + scope.format = function(cmd, arg) { + document.execCommand(cmd, false, arg); + }; + + scope.cmdState = function(cmd) { + return document.queryCommandState(cmd); + }; + + scope.cmdValue = function(cmd) { + return document.queryCommandValue(cmd); + }; + + scope.createLink = function() { + var input = prompt('Enter the link URL'); + if (input && input !== undefined) + scope.format('createlink', input); + }; + + scope.insertImage = function() { + var input = prompt('Enter the image URL'); + if (input && input !== undefined) + scope.format('insertimage', input); + }; + + scope.setFont = function() { + scope.format('fontname', scope.font); + }; + + scope.setFontSize = function() { + scope.format('fontsize', scope.fontSize.value); + }; + + scope.setFormatBlock = function() { + scope.format('formatBlock', scope.formatBlock.value); + }; + + scope.setFontColor = function() { + scope.format('forecolor', scope.fontColor); + }; + + scope.setHiliteColor = function() { + scope.format('hiliteColor', scope.hiliteColor); + }; + scope.textareaCustomFunctions = scope.textareaCustomFunctions || {}; + for (var i in scope.textareaCustomFunctions) { + if (scope[i] == undefined) { + scope[i] = scope.textareaCustomFunctions[i]; + } else { + console.log('Cannot set custom function `' + i + '`. Already exists function or property'); + } + } + scope.format('enableobjectresizing', true); + scope.format('styleWithCSS', true); } - el = create(getMenuItem(menu[i][j])); - menuGroup.appendChild(el); - } - startDiv.appendChild(menuGroup); - } - return startDiv; - }; - function create(obj) { - var el; - if (obj.tag) { - el = document.createElement(obj.tag); - } else if (obj.text) { - el = document.createElement('span'); - } else { - console.log('cannot create this element.'); - el = document.createElement('span'); - return el; - } - if (obj.text && document.all) { - el.innerText = obj.text; - } else { - if(obj.text){ - el.textContent = obj.text; - }else{ - el.textContent = ""; + }) + .factory('wysiwgGui', function(wysiwgGuiElements) { + + var ELEMENTS = wysiwgGuiElements; + var custom = {}; + + var setCustomElements = function(el) { + custom = el; + }; + + var getMenuGroup = function() { + return { + tag: 'div', + classes: 'btn-group btn-group-sm wysiwyg-btn-group-margin', + }; + }; + + var getMenuItem = function(item) { + return ELEMENTS[item] || {}; + }; + + var createMenu = function(menu) { + + angular.extend(ELEMENTS, custom); + + //Get the default menu or the passed in menu + if (angular.isDefined(menu) && menu !== '') { + menu = menu; //stringToArray(menu) + } else { + menu = DEFAULT_MENU; + } + + //create div to add everything to. + var startDiv = document.createElement('div'); + var el; + + for (var i = 0; i < menu.length; i++) { + var menuGroup = create(getMenuGroup()); + + for (var j = 0; j < menu[i].length; j++) { + //link has two functions link and unlink + if (menu[i][j] === 'link') { + el = create(getMenuItem('unlink')); + menuGroup.appendChild(el); + } + + el = create(getMenuItem(menu[i][j])); + menuGroup.appendChild(el); + } + + startDiv.appendChild(menuGroup); + } + return startDiv; + }; + + + function create(obj) { + var el; + if (obj.tag) { + el = document.createElement(obj.tag); + } else if (obj.text) { + el = document.createElement('span'); + } else { + console.log('cannot create this element.'); + el = document.createElement('span'); + return el; + } + + if (obj.text && document.all) { + el.innerText = obj.text; + } else if (obj.text) { + el.textContent = obj.text; + } + + if (obj.classes) { + el.className = obj.classes; + } + + if (obj.html) { + el.innerHTML = obj.html; + } + + if (obj.attributes && obj.attributes.length) { + for (var i in obj.attributes) { + var attr = obj.attributes[i]; + if (attr.name && attr.value) { + el.setAttribute(attr.name, attr.value); + } + } + } + + if (obj.data && obj.data.length) { + for (var item in obj.data) { + el.appendChild(create(obj.data[item])); + } + } + + return el; } - } - if (obj.classes) { - el.className = obj.classes; - } - if (obj.html) { - el.innerHTML = obj.html; - } - if (obj.attributes && obj.attributes.length) { - for (var i in obj.attributes) { - var attr = obj.attributes[i]; - if (attr.name && attr.value) { - el.setAttribute(attr.name, attr.value); + + return { + createMenu: createMenu, + setCustomElements: setCustomElements + }; + + }) + .value('wysiwgGuiElements', { + 'bold': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Bold' + }, { + name: 'ng-click', + value: 'format(\'bold\')' + }, { + name: 'ng-class', + value: '{ active: isBold }' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-bold' + }] + }, + 'italic': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Italic' + }, { + name: 'ng-click', + value: 'format(\'italic\')' + }, { + name: 'ng-class', + value: '{ active: isItalic }' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-italic' + }] + }, + 'underline': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Underline' + }, { + name: 'ng-click', + value: 'format(\'underline\')' + }, { + name: 'ng-class', + value: '{ active: isUnderlined }' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-underline' + }] + }, + 'strikethrough': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Strikethrough' + }, { + name: 'ng-click', + value: 'format(\'strikethrough\')' + }, { + name: 'ng-class', + value: '{ active: isStrikethrough }' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-strikethrough' + }] + }, + 'subscript': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Subscript' + }, { + name: 'ng-click', + value: 'format(\'subscript\')' + }, { + name: 'ng-class', + value: '{ active: isSubscript }' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-subscript' + }] + }, + 'superscript': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Superscript' + }, { + name: 'ng-click', + value: 'format(\'superscript\')' + }, { + name: 'ng-class', + value: '{ active: isSuperscript }' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-superscript' + }] + }, + 'remove-format': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Remove Formatting' + }, { + name: 'ng-click', + value: 'format(\'removeFormat\')' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-eraser' + }] + }, + 'ordered-list': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Ordered List' + }, { + name: 'ng-click', + value: 'format(\'insertorderedlist\')' + }, { + name: 'ng-class', + value: '{ active: isOrderedList }' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-list-ol' + }] + }, + 'unordered-list': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Unordered List' + }, { + name: 'ng-click', + value: 'format(\'insertunorderedlist\')' + }, { + name: 'ng-class', + value: '{ active: isUnorderedList }' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-list-ul' + }] + }, + 'outdent': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Outdent' + }, { + name: 'ng-click', + value: 'format(\'outdent\')' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-outdent' + }] + }, + 'indent': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Indent' + }, { + name: 'ng-click', + value: 'format(\'indent\')' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-indent' + }] + }, + 'left-justify': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Left Justify' + }, { + name: 'ng-click', + value: 'format(\'justifyleft\')' + }, { + name: 'ng-class', + value: '{ active: isLeftJustified }' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-align-left' + }] + }, + 'center-justify': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Center Justify' + }, { + name: 'ng-click', + value: 'format(\'justifycenter\')' + }, { + name: 'ng-class', + value: '{ active: isCenterJustified }' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-align-center' + }] + }, + 'right-justify': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Right Justify' + }, { + name: 'ng-click', + value: 'format(\'justifyright\')' + }, { + name: 'ng-class', + value: '{ active: isRightJustified }' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-align-right' + }] + }, + 'code': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Code' + }, { + name: 'ng-click', + value: 'format(\'formatblock\', \'pre\')' + }, { + name: 'ng-class', + value: '{ active: isPre }' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-code' + }] + }, + 'quote': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Quote' + }, { + name: 'ng-click', + value: 'format(\'formatblock\', \'blockquote\')' + }, { + name: 'ng-class', + value: '{ active: isBlockquote }' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-quote-right' + }] + }, + 'paragraph': { + tag: 'button', + classes: 'btn btn-default', + text: 'P', + attributes: [{ + name: 'title', + value: 'Paragragh' + }, { + name: 'ng-click', + value: 'format(\'insertParagraph\')' + }, { + name: 'ng-class', + value: '{ active: isParagraph }' + }, { + name: 'type', + value: 'button' + }] + }, + 'image': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Image' + }, { + name: 'ng-click', + value: 'insertImage()' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-picture-o' + }] + }, + 'font-color': { + tag: 'button', + classes: 'btn btn-default wysiwyg-colorpicker wysiwyg-fontcolor', + text: 'A', + attributes: [{ + name: 'title', + value: 'Font Color' + }, { + name: 'colorpicker', + value: 'rgba' + }, { + name: 'colorpicker-position', + value: 'top' + }, { + name: 'ng-model', + value: 'fontColor' + }, { + name: 'ng-change', + value: 'setFontColor()' + }, { + name: 'type', + value: 'button' + }] + }, + 'hilite-color': { + tag: 'button', + classes: 'btn btn-default wysiwyg-colorpicker wysiwyg-fontcolor', + text: 'H', + attributes: [{ + name: 'title', + value: 'Hilite Color' + }, { + name: 'colorpicker', + value: 'rgba' + }, { + name: 'colorpicker-position', + value: 'top' + }, { + name: 'ng-model', + value: 'hiliteColor' + }, { + name: 'ng-change', + value: 'setHiliteColor()' + }, { + name: 'type', + value: 'button' + }] + }, + 'font': { + tag: 'select', + classes: 'form-control wysiwyg-select', + attributes: [{ + name: 'title', + value: 'Image' + }, { + name: 'ng-model', + value: 'font' + }, { + name: 'ng-options', + value: 'f for f in fonts' + }, { + name: 'ng-change', + value: 'setFont()' + }] + }, + 'font-size': { + tag: 'select', + classes: 'form-control wysiwyg-select', + attributes: [{ + name: 'title', + value: 'Image' + }, { + name: 'ng-model', + value: 'fontSize' + }, { + name: 'ng-options', + value: 'f.size for f in fontSizes' + }, { + name: 'ng-change', + value: 'setFontSize()' + }] + }, + 'format-block': { + tag: 'select', + classes: 'form-control wysiwyg-select', + attributes: [{ + name: 'title', + value: 'Format Block' + }, { + name: 'ng-model', + value: 'formatBlock' + }, { + name: 'ng-options', + value: 'f.name for f in formatBlocks' + }, { + name: 'ng-change', + value: 'setFormatBlock()' + }] + }, + 'link': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Link' + }, { + name: 'ng-click', + value: 'createLink()' + }, { + name: 'ng-show', + value: '!isLink' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-link' + }] + }, + 'unlink': { + tag: 'button', + classes: 'btn btn-default', + attributes: [{ + name: 'title', + value: 'Unlink' + }, { + name: 'ng-click', + value: 'format(\'unlink\')' + }, { + name: 'ng-show', + value: 'isLink' + }, { + name: 'type', + value: 'button' + }], + data: [{ + tag: 'i', + classes: 'fa fa-unlink' + }] } - } - } - if (obj.data && obj.data.length) { - for (var item in obj.data) { - el.appendChild(create(obj.data[item])); - } - } - return el; - } - return { - createMenu: createMenu, - setCustomElements: setCustomElements - }; - } - ]).value('wysiwgGuiElements', { - 'bold': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Bold' - }, - { - name: 'ng-click', - value: 'format(\'bold\')' - }, - { - name: 'ng-class', - value: '{ active: isBold }' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-bold' - }] - }, - 'italic': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Italic' - }, - { - name: 'ng-click', - value: 'format(\'italic\')' - }, - { - name: 'ng-class', - value: '{ active: isItalic }' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-italic' - }] - }, - 'underline': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Underline' - }, - { - name: 'ng-click', - value: 'format(\'underline\')' - }, - { - name: 'ng-class', - value: '{ active: isUnderlined }' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-underline' - }] - }, - 'strikethrough': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Strikethrough' - }, - { - name: 'ng-click', - value: 'format(\'strikethrough\')' - }, - { - name: 'ng-class', - value: '{ active: isStrikethrough }' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-strikethrough' - }] - }, - 'subscript': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Subscript' - }, - { - name: 'ng-click', - value: 'format(\'subscript\')' - }, - { - name: 'ng-class', - value: '{ active: isSubscript }' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-subscript' - }] - }, - 'superscript': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Superscript' - }, - { - name: 'ng-click', - value: 'format(\'superscript\')' - }, - { - name: 'ng-class', - value: '{ active: isSuperscript }' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-superscript' - }] - }, - 'remove-format': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Remove Formatting' - }, - { - name: 'ng-click', - value: 'format(\'removeFormat\')' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-eraser' - }] - }, - 'ordered-list': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Ordered List' - }, - { - name: 'ng-click', - value: 'format(\'insertorderedlist\')' - }, - { - name: 'ng-class', - value: '{ active: isOrderedList }' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-list-ol' - }] - }, - 'unordered-list': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Unordered List' - }, - { - name: 'ng-click', - value: 'format(\'insertunorderedlist\')' - }, - { - name: 'ng-class', - value: '{ active: isUnorderedList }' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-list-ul' - }] - }, - 'outdent': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Outdent' - }, - { - name: 'ng-click', - value: 'format(\'outdent\')' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-outdent' - }] - }, - 'indent': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Indent' - }, - { - name: 'ng-click', - value: 'format(\'indent\')' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-indent' - }] - }, - 'left-justify': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Left Justify' - }, - { - name: 'ng-click', - value: 'format(\'justifyleft\')' - }, - { - name: 'ng-class', - value: '{ active: isLeftJustified }' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-align-left' - }] - }, - 'center-justify': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Center Justify' - }, - { - name: 'ng-click', - value: 'format(\'justifycenter\')' - }, - { - name: 'ng-class', - value: '{ active: isCenterJustified }' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-align-center' - }] - }, - 'right-justify': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Right Justify' - }, - { - name: 'ng-click', - value: 'format(\'justifyright\')' - }, - { - name: 'ng-class', - value: '{ active: isRightJustified }' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-align-right' - }] - }, - 'code': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Code' - }, - { - name: 'ng-click', - value: 'format(\'formatblock\', \'pre\')' - }, - { - name: 'ng-class', - value: '{ active: isPre }' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-code' - }] - }, - 'quote': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Quote' - }, - { - name: 'ng-click', - value: 'format(\'formatblock\', \'blockquote\')' - }, - { - name: 'ng-class', - value: '{ active: isBlockquote }' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-quote-right' - }] - }, - 'paragraph': { - tag: 'button', - classes: 'btn btn-default', - text: 'P', - attributes: [ - { - name: 'title', - value: 'Paragragh' - }, - { - name: 'ng-click', - value: 'format(\'insertParagraph\')' - }, - { - name: 'ng-class', - value: '{ active: isParagraph }' - }, - { - name: 'type', - value: 'button' - } - ] - }, - 'image': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Image' - }, - { - name: 'ng-click', - value: 'insertImage()' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-picture-o' - }] - }, - 'font-color': { - tag: 'button', - classes: 'btn btn-default wysiwyg-colorpicker wysiwyg-fontcolor', - text: 'A', - attributes: [ - { - name: 'title', - value: 'Font Color' - }, - { - name: 'colorpicker', - value: 'rgba' - }, - { - name: 'colorpicker-position', - value: 'top' - }, - { - name: 'ng-model', - value: 'fontColor' - }, - { - name: 'ng-change', - value: 'setFontColor()' - }, - { - name: 'type', - value: 'button' - } - ] - }, - 'hilite-color': { - tag: 'button', - classes: 'btn btn-default wysiwyg-colorpicker wysiwyg-fontcolor', - text: 'H', - attributes: [ - { - name: 'title', - value: 'Hilite Color' - }, - { - name: 'colorpicker', - value: 'rgba' - }, - { - name: 'colorpicker-position', - value: 'top' - }, - { - name: 'ng-model', - value: 'hiliteColor' - }, - { - name: 'ng-change', - value: 'setHiliteColor()' - }, - { - name: 'type', - value: 'button' - } - ] - }, - 'font': { - tag: 'select', - classes: 'form-control wysiwyg-select', - attributes: [ - { - name: 'title', - value: 'Font' - }, - { - name: 'ng-model', - value: 'font' - }, - { - name: 'ng-options', - value: 'f for f in fonts' - }, - { - name: 'ng-change', - value: 'setFont()' - } - ] - }, - 'font-size': { - tag: 'select', - classes: 'form-control wysiwyg-select', - attributes: [ - { - name: 'title', - value: 'Image' - }, - { - name: 'ng-model', - value: 'fontSize' - }, - { - name: 'ng-options', - value: 'f.size for f in fontSizes' - }, - { - name: 'ng-change', - value: 'setFontSize()' - } - ] - }, - 'format-block': { - tag: 'select', - classes: 'form-control wysiwyg-select', - attributes: [ - { - name: 'title', - value: 'Format Block' - }, - { - name: 'ng-model', - value: 'formatBlock' - }, - { - name: 'ng-options', - value: 'f.name for f in formatBlocks' - }, - { - name: 'ng-change', - value: 'setFormatBlock()' - } - ] - }, - 'link': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Link' - }, - { - name: 'ng-click', - value: 'createLink()' - }, - { - name: 'ng-show', - value: '!isLink' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-link' - }] - }, - 'unlink': { - tag: 'button', - classes: 'btn btn-default', - attributes: [ - { - name: 'title', - value: 'Unlink' - }, - { - name: 'ng-click', - value: 'format(\'unlink\')' - }, - { - name: 'ng-show', - value: 'isLink' - }, - { - name: 'type', - value: 'button' - } - ], - data: [{ - tag: 'i', - classes: 'fa fa-unlink' - }] - } - }); -}(angular)); + }); +})(angular); \ No newline at end of file diff --git a/dist/angular-wysiwyg.min.js b/dist/angular-wysiwyg.min.js index 1e94c44..bcfc4c6 100644 --- a/dist/angular-wysiwyg.min.js +++ b/dist/angular-wysiwyg.min.js @@ -1 +1 @@ -!function(t,e){"use strict";var a=[["bold","italic","underline","strikethrough","subscript","superscript"],["format-block"],["font"],["font-size"],["font-color","hilite-color"],["remove-format"],["ordered-list","unordered-list","outdent","indent"],["left-justify","center-justify","right-justify"],["code","quote","paragraph"],["link","image"]];t.module("wysiwyg.module",["colorpicker.module"]).directive("wysiwyg",["$timeout","wysiwgGui","$compile",function(a,n,i){function l(l,s,o,r){function u(){c(),m(),f(),d()}function c(){n.setCustomElements(l.textareaCustomMenu);var t=s.children("div.wysiwyg-menu")[0];t.appendChild(n.createMenu(l.textareaMenu)),i(t)(l)}function m(){l.$watch("disabled",function(e){t.element("div.wysiwyg-menu").find("button").each(function(){t.element(this).attr("disabled",e)}),t.element("div.wysiwyg-menu").find("select").each(function(){t.element(this).attr("disabled",e)})})}function f(){"true"===o.enableBootstrapTitle&&o.enableBootstrapTitle!==e&&s.find("button[title]").tooltip({container:"body"})}function d(){t.element(".wysiwyg-menu").find("button").on("click",function(){var e=t.element(this);l.$emit("wysiwyg.click",e.attr("title")||e.attr("data-original-title"))}),b.on("input keyup paste mouseup",function(){var t=b.html();"
"==t&&(t=""),r.$setViewValue(t)}),b.on("keydown",function(t){if(9==t.keyCode){{var e=(b.html(),window.getSelection());e.anchorOffset}t.preventDefault()}}),b.on("click keyup focus mouseup",function(){a(function(){l.isBold=l.cmdState("bold"),l.isUnderlined=l.cmdState("underline"),l.isStrikethrough=l.cmdState("strikethrough"),l.isItalic=l.cmdState("italic"),l.isSuperscript=g("SUP"),l.isSubscript=g("SUB"),l.isRightJustified=l.cmdState("justifyright"),l.isLeftJustified=l.cmdState("justifyleft"),l.isCenterJustified=l.cmdState("justifycenter"),l.isPre="pre"===l.cmdValue("formatblock"),l.isBlockquote="blockquote"===l.cmdValue("formatblock"),l.isOrderedList=l.cmdState("insertorderedlist"),l.isUnorderedList=l.cmdState("insertunorderedlist"),l.fonts.forEach(function(t){return l.cmdValue("fontname").indexOf(t)>-1?(l.font=t,!1):void 0}),l.cmdValue("formatblock").toLowerCase(),l.formatBlocks.forEach(function(t){return l.cmdValue("formatblock").toLowerCase()===t.value.toLowerCase()?(l.formatBlock=t,!1):void 0}),l.fontSizes.forEach(function(t){return l.cmdValue("fontsize")===t.value?(l.fontSize=t,!1):void 0}),l.hiliteColor=v(),s.find("button.wysiwyg-hiliteColor").css("background-color",l.hiliteColor),l.fontColor=l.cmdValue("forecolor"),s.find("button.wysiwyg-fontcolor").css("color",l.fontColor),l.isLink=g("A")},0)})}function g(t){var e=window.getSelection().getRangeAt(0);return e&&(e.startContainer.parentNode.tagName===t.toUpperCase()||e.endContainer.parentNode.tagName===t.toUpperCase())?!0:!1}function v(){var e=window.getSelection().getRangeAt(0);if(e){var a=t.element(e.startContainer.parentNode).attr("style");if(!t.isDefined(a))return!1;for(var n=a.split(";"),i=0;i
',restrict:"E",scope:{value:"=ngModel",textareaHeight:"@textareaHeight",textareaName:"@textareaName",textareaClass:"@textareaClass",textareaRequired:"@textareaRequired",textareaId:"@textareaId",textareaMenu:"=textareaMenu",textareaCustomMenu:"=textareaCustomMenu",fn:"&",disabled:"=?disabled"},replace:!0,require:"ngModel",link:l,transclude:!0}}]).factory("wysiwgGui",["wysiwgGuiElements",function(e){function n(t){var e;if(t.tag)e=document.createElement(t.tag);else{if(!t.text)return console.log("cannot create this element."),e=document.createElement("span");e=document.createElement("span")}if(t.text&&document.all?e.innerText=t.text:e.textContent=t.text,t.classes&&(e.className=t.classes),t.html&&(e.innerHTML=t.html),t.attributes&&t.attributes.length)for(var a in t.attributes){var i=t.attributes[a];i.name&&i.value&&e.setAttribute(i.name,i.value)}if(t.data&&t.data.length)for(var l in t.data)e.appendChild(n(t.data[l]));return e}var i=e,l={},s=function(t){l=t},o=function(){return{tag:"div",classes:"btn-group btn-group-sm wysiwyg-btn-group-margin"}},r=function(t){return i[t]||{}},u=function(e){t.extend(i,l),e=t.isDefined(e)&&""!==e?e:a;for(var s,u=document.createElement("div"),c=0;c"==t&&(t=""),r.$setViewValue(t)}),b.on("keydown",function(t){if(9==t.keyCode){{var e=(b.html(),window.getSelection());e.anchorOffset}t.preventDefault()}}),b.on("click keyup focus mouseup",function(){a(function(){l.isBold=l.cmdState("bold"),l.isUnderlined=l.cmdState("underline"),l.isStrikethrough=l.cmdState("strikethrough"),l.isItalic=l.cmdState("italic"),l.isSuperscript=g("SUP"),l.isSubscript=g("SUB"),l.isRightJustified=l.cmdState("justifyright"),l.isLeftJustified=l.cmdState("justifyleft"),l.isCenterJustified=l.cmdState("justifycenter"),l.isPre="pre"===l.cmdValue("formatblock"),l.isBlockquote="blockquote"===l.cmdValue("formatblock"),l.isOrderedList=l.cmdState("insertorderedlist"),l.isUnorderedList=l.cmdState("insertunorderedlist"),l.fonts.forEach(function(t){return l.cmdValue("fontname").indexOf(t)>-1?(l.font=t,!1):void 0}),l.cmdValue("formatblock").toLowerCase(),l.formatBlocks.forEach(function(t){return l.cmdValue("formatblock").toLowerCase()===t.value.toLowerCase()?(l.formatBlock=t,!1):void 0}),l.fontSizes.forEach(function(t){return l.cmdValue("fontsize")===t.value?(l.fontSize=t,!1):void 0}),l.hiliteColor=v(),s.find("button.wysiwyg-hiliteColor").css("background-color",l.hiliteColor),l.fontColor=l.cmdValue("forecolor"),s.find("button.wysiwyg-fontcolor").css("color",l.fontColor),l.isLink=g("A")},0)})}function g(t){var e=window.getSelection().getRangeAt(0);return e&&(e.startContainer.parentNode.tagName===t.toUpperCase()||e.endContainer.parentNode.tagName===t.toUpperCase())?!0:!1}function v(){var e=window.getSelection().getRangeAt(0);if(e){var a=t.element(e.startContainer.parentNode).attr("style");if(!t.isDefined(a))return!1;for(var n=a.split(";"),i=0;i
',restrict:"E",scope:{value:"=ngModel",textareaHeight:"@textareaHeight",textareaName:"@textareaName",textareaClass:"@textareaClass",textareaRequired:"@textareaRequired",textareaId:"@textareaId",textareaMenu:"=textareaMenu",textareaCustomMenu:"=textareaCustomMenu",fn:"&",disabled:"=?disabled",textareaCustomFunctions:"=textareaCustomFunctions"},replace:!0,require:"ngModel",link:l,transclude:!0}}).factory("wysiwgGui",function(e){function n(t){var e;if(t.tag)e=document.createElement(t.tag);else{if(!t.text)return console.log("cannot create this element."),e=document.createElement("span");e=document.createElement("span")}if(t.text&&document.all?e.innerText=t.text:t.text&&(e.textContent=t.text),t.classes&&(e.className=t.classes),t.html&&(e.innerHTML=t.html),t.attributes&&t.attributes.length)for(var a in t.attributes){var i=t.attributes[a];i.name&&i.value&&e.setAttribute(i.name,i.value)}if(t.data&&t.data.length)for(var l in t.data)e.appendChild(n(t.data[l]));return e}var i=e,l={},s=function(t){l=t},o=function(){return{tag:"div",classes:"btn-group btn-group-sm wysiwyg-btn-group-margin"}},r=function(t){return i[t]||{}},u=function(e){t.extend(i,l),e=t.isDefined(e)&&""!==e?e:a;for(var s,u=document.createElement("div"),c=0;c Date: Thu, 17 Sep 2015 18:36:57 -0300 Subject: [PATCH 2/4] Doc Custom functions --- README.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1364091..6c2de14 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,9 @@ Option|Description **textarea-name** | The name attribute of the editable div **textarea-required**| True/False HTML/AngularJS required validation **enable-bootstrap-title**| True/False whether or not to show the button hover title styled with bootstrap -**textarea-menu** | Cusomize the wysiwyg buttons and button groups ***See Below** If nothing is specified then the default buttons and groups will be shown. +**textarea-menu** | Customize the wysiwyg buttons and button groups ***See Below** If nothing is specified then the default buttons and groups will be shows. +**textarea-custom-menu** | Create a customized menu +**textarea-custom-functions** | Allow add your custom function to your custom element **disabled** | Disable the buttons and wysiwig area Buttons @@ -115,7 +117,70 @@ quote | link | image | +Custom elements +-------------- +You can add you own button or select element +````html + +``` - +```javascript +var insertVariables = { + '0': 'Choose one', + 'a': 'Insert a', + 'b': 'Insert b' + }; + var insertOptions = []; + for (var i in insertVariables) { + insertOptions.push({ + tag: 'option', + attributes: [{ + name: 'value', + value: i + }], + text: insertVariables[i] + }); + } + $scope.yourModel = {}; + $scope.yourModel.customMenu = { + 'myInsertElement': { + tag: 'select', + classes: 'form-control wysiwyg-select', + attributes: [{ + name: 'ng-model', + value: 'myInsertElement' + }, { + name: 'ng-init', + value: 'myInsertElement = "0"' + }, { + name: 'ng-change', + value: 'chInsert(this)' + }], + data: insertOptions, + }, + }; + + $scope.yourModel.customFunctions = { + chInsert: function(scope) { + if (scope.myInsertElement != '0') { + document.execCommand("insertHTML", false, scope.myInsertElement); + scope.myInsertElement = '0'; + } + } + }; + $scope.yourModel.menu = [ + ['bold', 'italic', 'underline', 'strikethrough', 'subscript', 'superscript'], + ['format-block'], + ['font'], + ['font-size'], + ['font-color', 'hilite-color'], + ['remove-format'], + ['ordered-list', 'unordered-list', 'outdent', 'indent'], + ['left-justify', 'center-justify', 'right-justify'], + ['code', 'quote', 'paragraph'], + ['link', 'image'], + ['myInsertElement'] + ]; +``` \ No newline at end of file From ba621350f49f356d3cb83bdefc20e7fb5f52d38f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Felipe=20Paiva?= Date: Fri, 18 Sep 2015 10:18:24 -0300 Subject: [PATCH 3/4] Fix minified error The tool used to generate the code was making errors on directive --- dist/angular-wysiwyg.min.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dist/angular-wysiwyg.min.js b/dist/angular-wysiwyg.min.js index bcfc4c6..9550489 100644 --- a/dist/angular-wysiwyg.min.js +++ b/dist/angular-wysiwyg.min.js @@ -1 +1,2 @@ -!function(t,e){"use strict";var a=[["bold","italic","underline","strikethrough","subscript","superscript"],["format-block"],["font"],["font-size"],["font-color","hilite-color"],["remove-format"],["ordered-list","unordered-list","outdent","indent"],["left-justify","center-justify","right-justify"],["code","quote","paragraph"],["link","image"]];t.module("wysiwyg.module",["colorpicker.module"]).directive("wysiwyg",function(a,n,i){function l(l,s,o,r){function u(){c(),m(),f(),d()}function c(){n.setCustomElements(l.textareaCustomMenu);var t=s.children("div.wysiwyg-menu")[0];t.appendChild(n.createMenu(l.textareaMenu)),i(t)(l)}function m(){l.$watch("disabled",function(e){t.element("div.wysiwyg-menu").find("button").each(function(){t.element(this).attr("disabled",e)}),t.element("div.wysiwyg-menu").find("select").each(function(){t.element(this).attr("disabled",e)})})}function f(){"true"===o.enableBootstrapTitle&&o.enableBootstrapTitle!==e&&s.find("button[title]").tooltip({container:"body"})}function d(){t.element(".wysiwyg-menu").find("button").on("click",function(){var e=t.element(this);l.$emit("wysiwyg.click",e.attr("title")||e.attr("data-original-title"))}),b.on("input keyup paste mouseup",function(){var t=b.html();"
"==t&&(t=""),r.$setViewValue(t)}),b.on("keydown",function(t){if(9==t.keyCode){{var e=(b.html(),window.getSelection());e.anchorOffset}t.preventDefault()}}),b.on("click keyup focus mouseup",function(){a(function(){l.isBold=l.cmdState("bold"),l.isUnderlined=l.cmdState("underline"),l.isStrikethrough=l.cmdState("strikethrough"),l.isItalic=l.cmdState("italic"),l.isSuperscript=g("SUP"),l.isSubscript=g("SUB"),l.isRightJustified=l.cmdState("justifyright"),l.isLeftJustified=l.cmdState("justifyleft"),l.isCenterJustified=l.cmdState("justifycenter"),l.isPre="pre"===l.cmdValue("formatblock"),l.isBlockquote="blockquote"===l.cmdValue("formatblock"),l.isOrderedList=l.cmdState("insertorderedlist"),l.isUnorderedList=l.cmdState("insertunorderedlist"),l.fonts.forEach(function(t){return l.cmdValue("fontname").indexOf(t)>-1?(l.font=t,!1):void 0}),l.cmdValue("formatblock").toLowerCase(),l.formatBlocks.forEach(function(t){return l.cmdValue("formatblock").toLowerCase()===t.value.toLowerCase()?(l.formatBlock=t,!1):void 0}),l.fontSizes.forEach(function(t){return l.cmdValue("fontsize")===t.value?(l.fontSize=t,!1):void 0}),l.hiliteColor=v(),s.find("button.wysiwyg-hiliteColor").css("background-color",l.hiliteColor),l.fontColor=l.cmdValue("forecolor"),s.find("button.wysiwyg-fontcolor").css("color",l.fontColor),l.isLink=g("A")},0)})}function g(t){var e=window.getSelection().getRangeAt(0);return e&&(e.startContainer.parentNode.tagName===t.toUpperCase()||e.endContainer.parentNode.tagName===t.toUpperCase())?!0:!1}function v(){var e=window.getSelection().getRangeAt(0);if(e){var a=t.element(e.startContainer.parentNode).attr("style");if(!t.isDefined(a))return!1;for(var n=a.split(";"),i=0;i
',restrict:"E",scope:{value:"=ngModel",textareaHeight:"@textareaHeight",textareaName:"@textareaName",textareaClass:"@textareaClass",textareaRequired:"@textareaRequired",textareaId:"@textareaId",textareaMenu:"=textareaMenu",textareaCustomMenu:"=textareaCustomMenu",fn:"&",disabled:"=?disabled",textareaCustomFunctions:"=textareaCustomFunctions"},replace:!0,require:"ngModel",link:l,transclude:!0}}).factory("wysiwgGui",function(e){function n(t){var e;if(t.tag)e=document.createElement(t.tag);else{if(!t.text)return console.log("cannot create this element."),e=document.createElement("span");e=document.createElement("span")}if(t.text&&document.all?e.innerText=t.text:t.text&&(e.textContent=t.text),t.classes&&(e.className=t.classes),t.html&&(e.innerHTML=t.html),t.attributes&&t.attributes.length)for(var a in t.attributes){var i=t.attributes[a];i.name&&i.value&&e.setAttribute(i.name,i.value)}if(t.data&&t.data.length)for(var l in t.data)e.appendChild(n(t.data[l]));return e}var i=e,l={},s=function(t){l=t},o=function(){return{tag:"div",classes:"btn-group btn-group-sm wysiwyg-btn-group-margin"}},r=function(t){return i[t]||{}},u=function(e){t.extend(i,l),e=t.isDefined(e)&&""!==e?e:a;for(var s,u=document.createElement("div"),c=0;c'+''+'
'+'
'+'',restrict:'E',scope:{value:'=ngModel',textareaHeight:'@textareaHeight',textareaName:'@textareaName',textareaClass:'@textareaClass',textareaRequired:'@textareaRequired',textareaId:'@textareaId',textareaMenu:'=textareaMenu',textareaCustomMenu:'=textareaCustomMenu',fn:'&',disabled:'=?disabled',textareaCustomFunctions:'=textareaCustomFunctions'},replace:true,require:'ngModel',link:link,transclude:true};function link(scope,element,attrs,ngModelController){var textarea=element.find('div.wysiwyg-textarea');scope.isLink=false;scope.fontSizes=[{value:'1',size:'10px'},{value:'2',size:'13px'},{value:'3',size:'16px'},{value:'4',size:'18px'},{value:'5',size:'24px'},{value:'6',size:'32px'},{value:'7',size:'48px'}];scope.formatBlocks=[{name:'Heading Blocks',value:'div'},{name:'Heading 1',value:'h1'},{name:'Heading 2',value:'h2'},{name:'Heading 3',value:'h3'},{name:'Heading 4',value:'h4'},{name:'Heading 5',value:'h5'},{name:'Heading 6',value:'h6'},];scope.formatBlock=scope.formatBlocks[0];scope.fontSize=scope.fontSizes[1];if(angular.isArray(scope.cssClasses)){scope.cssClasses.unshift('css');scope.cssClass=scope.cssClasses[0];}scope.fonts=['Georgia','Palatino Linotype','Times New Roman','Arial','Helvetica','Arial Black','Comic Sans MS','Impact','Lucida Sans Unicode','Tahoma','Trebuchet MS','Verdana','Courier New','Lucida Console','Helvetica Neue'].sort();scope.font=scope.fonts[6];init();function init(){compileMenu();configureDisabledWatch();configureBootstrapTitle();configureListeners();}function compileMenu(){wysiwgGui.setCustomElements(scope.textareaCustomMenu);var menuDiv=element.children('div.wysiwyg-menu')[0];menuDiv.appendChild(wysiwgGui.createMenu(scope.textareaMenu));$compile(menuDiv)(scope);}function configureDisabledWatch(){scope.$watch('disabled',function(newValue){angular.element('div.wysiwyg-menu').find('button').each(function(){angular.element(this).attr('disabled',newValue);});angular.element('div.wysiwyg-menu').find('select').each(function(){angular.element(this).attr('disabled',newValue);});});}function configureBootstrapTitle(){if(attrs.enableBootstrapTitle==='true'&&attrs.enableBootstrapTitle!==undefined){element.find('button[title]').tooltip({container:'body'});}}function insertTab(html,position){var begining=html.substr(0,position);var end=html.substr(position);return begining+' '+end;}function configureListeners(){angular.element('.wysiwyg-menu').find('button').on('click',function(){var title=angular.element(this);scope.$emit('wysiwyg.click',title.attr('title')||title.attr('data-original-title'));});textarea.on('input keyup paste mouseup',function(){var html=textarea.html();if(html=='
'){html='';}ngModelController.$setViewValue(html);});textarea.on('keydown',function(event){if(event.keyCode==9){var TAB_SPACES=4;var html=textarea.html();var selection=window.getSelection();var position=selection.anchorOffset;event.preventDefault();}});textarea.on('click keyup focus mouseup',function(){$timeout(function(){scope.isBold=scope.cmdState('bold');scope.isUnderlined=scope.cmdState('underline');scope.isStrikethrough=scope.cmdState('strikethrough');scope.isItalic=scope.cmdState('italic');scope.isSuperscript=itemIs('SUP');scope.isSubscript=itemIs('SUB');scope.isRightJustified=scope.cmdState('justifyright');scope.isLeftJustified=scope.cmdState('justifyleft');scope.isCenterJustified=scope.cmdState('justifycenter');scope.isPre=scope.cmdValue('formatblock')==='pre';scope.isBlockquote=scope.cmdValue('formatblock')==='blockquote';scope.isOrderedList=scope.cmdState('insertorderedlist');scope.isUnorderedList=scope.cmdState('insertunorderedlist');scope.fonts.forEach(function(v,k){if(scope.cmdValue('fontname').indexOf(v)>-1){scope.font=v;return false;}});scope.cmdValue('formatblock').toLowerCase();scope.formatBlocks.forEach(function(v,k){if(scope.cmdValue('formatblock').toLowerCase()===v.value.toLowerCase()){scope.formatBlock=v;return false;}});scope.fontSizes.forEach(function(v,k){if(scope.cmdValue('fontsize')===v.value){scope.fontSize=v;return false;}});scope.hiliteColor=getHiliteColor();element.find('button.wysiwyg-hiliteColor').css('background-color',scope.hiliteColor);scope.fontColor=scope.cmdValue('forecolor');element.find('button.wysiwyg-fontcolor').css('color',scope.fontColor);scope.isLink=itemIs('A');},0);});}function itemIs(tag){var selection=window.getSelection().getRangeAt(0);if(selection){if(selection.startContainer.parentNode.tagName===tag.toUpperCase()||selection.endContainer.parentNode.tagName===tag.toUpperCase()){return true;}else{return false;}}else{return false;}}function getHiliteColor(){var selection=window.getSelection().getRangeAt(0);if(selection){var style=angular.element(selection.startContainer.parentNode).attr('style');if(!angular.isDefined(style))return false;var a=style.split(';');for(var i=0;i Date: Wed, 7 Oct 2015 14:50:18 -0300 Subject: [PATCH 4/4] more font sizes --- dist/angular-wysiwyg.js | 32 ++++++++++++++++++++++++++------ dist/angular-wysiwyg.min.js | 29 ++++++++++++++++++++++++++++- src/angular-wysiwyg.js | 30 ++++++++++++++++++++++++------ 3 files changed, 78 insertions(+), 13 deletions(-) diff --git a/dist/angular-wysiwyg.js b/dist/angular-wysiwyg.js index 4600035..d0e1589 100644 --- a/dist/angular-wysiwyg.js +++ b/dist/angular-wysiwyg.js @@ -14,6 +14,7 @@ Requires: Twitter-bootstrap, fontawesome, jquery, angularjs, bootstrap-color-picker (https://github.com/buberdds/angular-bootstrap-colorpicker) */ + /* TODO: tab support @@ -23,6 +24,7 @@ Requires: use compile fuction instead of $compile move button elements to js objects and use doc fragments */ + (function(angular, undefined) { 'use strict'; @@ -81,25 +83,43 @@ Requires: scope.fontSizes = [{ value: '1', - size: '10px' + size: '8px' }, { value: '2', - size: '13px' + size: '9px' }, { value: '3', - size: '16px' + size: '10px' }, { value: '4', - size: '18px' + size: '11px' }, { value: '5', - size: '24px' + size: '12px' }, { value: '6', - size: '32px' + size: '13px' }, { value: '7', + size: '14px' + }, { + value: '8', + size: '16px' + }, { + value: '9', + size: '18px' + }, { + value: '10', + size: '24px' + }, { + value: '11', + size: '32px' + }, { + value: '12', size: '48px' + }, { + value: '13', + size: '62px' }]; scope.formatBlocks = [{ diff --git a/dist/angular-wysiwyg.min.js b/dist/angular-wysiwyg.min.js index 9550489..952e83a 100644 --- a/dist/angular-wysiwyg.min.js +++ b/dist/angular-wysiwyg.min.js @@ -1,2 +1,29 @@ -(function(angular,undefined){'use strict';var DEFAULT_MENU=[['bold','italic','underline','strikethrough','subscript','superscript'],['format-block'],['font'],['font-size'],['font-color','hilite-color'],['remove-format'],['ordered-list','unordered-list','outdent','indent'],['left-justify','center-justify','right-justify'],['code','quote','paragraph'],['link','image']];angular.module('wysiwyg.module',['colorpicker.module']).directive('wysiwyg',function($timeout,wysiwgGui,$compile){return{template:'
'+''+'
'+'
'+'
',restrict:'E',scope:{value:'=ngModel',textareaHeight:'@textareaHeight',textareaName:'@textareaName',textareaClass:'@textareaClass',textareaRequired:'@textareaRequired',textareaId:'@textareaId',textareaMenu:'=textareaMenu',textareaCustomMenu:'=textareaCustomMenu',fn:'&',disabled:'=?disabled',textareaCustomFunctions:'=textareaCustomFunctions'},replace:true,require:'ngModel',link:link,transclude:true};function link(scope,element,attrs,ngModelController){var textarea=element.find('div.wysiwyg-textarea');scope.isLink=false;scope.fontSizes=[{value:'1',size:'10px'},{value:'2',size:'13px'},{value:'3',size:'16px'},{value:'4',size:'18px'},{value:'5',size:'24px'},{value:'6',size:'32px'},{value:'7',size:'48px'}];scope.formatBlocks=[{name:'Heading Blocks',value:'div'},{name:'Heading 1',value:'h1'},{name:'Heading 2',value:'h2'},{name:'Heading 3',value:'h3'},{name:'Heading 4',value:'h4'},{name:'Heading 5',value:'h5'},{name:'Heading 6',value:'h6'},];scope.formatBlock=scope.formatBlocks[0];scope.fontSize=scope.fontSizes[1];if(angular.isArray(scope.cssClasses)){scope.cssClasses.unshift('css');scope.cssClass=scope.cssClasses[0];}scope.fonts=['Georgia','Palatino Linotype','Times New Roman','Arial','Helvetica','Arial Black','Comic Sans MS','Impact','Lucida Sans Unicode','Tahoma','Trebuchet MS','Verdana','Courier New','Lucida Console','Helvetica Neue'].sort();scope.font=scope.fonts[6];init();function init(){compileMenu();configureDisabledWatch();configureBootstrapTitle();configureListeners();}function compileMenu(){wysiwgGui.setCustomElements(scope.textareaCustomMenu);var menuDiv=element.children('div.wysiwyg-menu')[0];menuDiv.appendChild(wysiwgGui.createMenu(scope.textareaMenu));$compile(menuDiv)(scope);}function configureDisabledWatch(){scope.$watch('disabled',function(newValue){angular.element('div.wysiwyg-menu').find('button').each(function(){angular.element(this).attr('disabled',newValue);});angular.element('div.wysiwyg-menu').find('select').each(function(){angular.element(this).attr('disabled',newValue);});});}function configureBootstrapTitle(){if(attrs.enableBootstrapTitle==='true'&&attrs.enableBootstrapTitle!==undefined){element.find('button[title]').tooltip({container:'body'});}}function insertTab(html,position){var begining=html.substr(0,position);var end=html.substr(position);return begining+' '+end;}function configureListeners(){angular.element('.wysiwyg-menu').find('button').on('click',function(){var title=angular.element(this);scope.$emit('wysiwyg.click',title.attr('title')||title.attr('data-original-title'));});textarea.on('input keyup paste mouseup',function(){var html=textarea.html();if(html=='
'){html='';}ngModelController.$setViewValue(html);});textarea.on('keydown',function(event){if(event.keyCode==9){var TAB_SPACES=4;var html=textarea.html();var selection=window.getSelection();var position=selection.anchorOffset;event.preventDefault();}});textarea.on('click keyup focus mouseup',function(){$timeout(function(){scope.isBold=scope.cmdState('bold');scope.isUnderlined=scope.cmdState('underline');scope.isStrikethrough=scope.cmdState('strikethrough');scope.isItalic=scope.cmdState('italic');scope.isSuperscript=itemIs('SUP');scope.isSubscript=itemIs('SUB');scope.isRightJustified=scope.cmdState('justifyright');scope.isLeftJustified=scope.cmdState('justifyleft');scope.isCenterJustified=scope.cmdState('justifycenter');scope.isPre=scope.cmdValue('formatblock')==='pre';scope.isBlockquote=scope.cmdValue('formatblock')==='blockquote';scope.isOrderedList=scope.cmdState('insertorderedlist');scope.isUnorderedList=scope.cmdState('insertunorderedlist');scope.fonts.forEach(function(v,k){if(scope.cmdValue('fontname').indexOf(v)>-1){scope.font=v;return false;}});scope.cmdValue('formatblock').toLowerCase();scope.formatBlocks.forEach(function(v,k){if(scope.cmdValue('formatblock').toLowerCase()===v.value.toLowerCase()){scope.formatBlock=v;return false;}});scope.fontSizes.forEach(function(v,k){if(scope.cmdValue('fontsize')===v.value){scope.fontSize=v;return false;}});scope.hiliteColor=getHiliteColor();element.find('button.wysiwyg-hiliteColor').css('background-color',scope.hiliteColor);scope.fontColor=scope.cmdValue('forecolor');element.find('button.wysiwyg-fontcolor').css('color',scope.fontColor);scope.isLink=itemIs('A');},0);});}function itemIs(tag){var selection=window.getSelection().getRangeAt(0);if(selection){if(selection.startContainer.parentNode.tagName===tag.toUpperCase()||selection.endContainer.parentNode.tagName===tag.toUpperCase()){return true;}else{return false;}}else{return false;}}function getHiliteColor(){var selection=window.getSelection().getRangeAt(0);if(selection){var style=angular.element(selection.startContainer.parentNode).attr('style');if(!angular.isDefined(style))return false;var a=style.split(';');for(var i=0;i'+''+'
'+'
'+'',restrict:'E',scope:{value:'=ngModel',textareaHeight:'@textareaHeight',textareaName:'@textareaName',textareaClass:'@textareaClass',textareaRequired:'@textareaRequired',textareaId:'@textareaId',textareaMenu:'=textareaMenu',textareaCustomMenu:'=textareaCustomMenu',fn:'&',disabled:'=?disabled',textareaCustomFunctions:'=textareaCustomFunctions'},replace:true,require:'ngModel',link:link,transclude:true};function link(scope,element,attrs,ngModelController){var textarea=element.find('div.wysiwyg-textarea');scope.isLink=false;scope.fontSizes=[{value:'1',size:'8px'},{value:'2',size:'9px'},{value:'3',size:'10px'},{value:'4',size:'11px'},{value:'5',size:'12px'},{value:'6',size:'13px'},{value:'7',size:'14px'},{value:'8',size:'16px'},{value:'9',size:'18px'},{value:'10',size:'24px'},{value:'11',size:'32px'},{value:'12',size:'48px'},{value:'13',size:'62px'}];scope.formatBlocks=[{name:'Heading Blocks',value:'div'},{name:'Heading 1',value:'h1'},{name:'Heading 2',value:'h2'},{name:'Heading 3',value:'h3'},{name:'Heading 4',value:'h4'},{name:'Heading 5',value:'h5'},{name:'Heading 6',value:'h6'},];scope.formatBlock=scope.formatBlocks[0];scope.fontSize=scope.fontSizes[1];if(angular.isArray(scope.cssClasses)){scope.cssClasses.unshift('css');scope.cssClass=scope.cssClasses[0];} +scope.fonts=['Georgia','Palatino Linotype','Times New Roman','Arial','Helvetica','Arial Black','Comic Sans MS','Impact','Lucida Sans Unicode','Tahoma','Trebuchet MS','Verdana','Courier New','Lucida Console','Helvetica Neue'].sort();scope.font=scope.fonts[6];init();function init(){compileMenu();configureDisabledWatch();configureBootstrapTitle();configureListeners();} +function compileMenu(){wysiwgGui.setCustomElements(scope.textareaCustomMenu);var menuDiv=element.children('div.wysiwyg-menu')[0];menuDiv.appendChild(wysiwgGui.createMenu(scope.textareaMenu));$compile(menuDiv)(scope);} +function configureDisabledWatch(){scope.$watch('disabled',function(newValue){angular.element('div.wysiwyg-menu').find('button').each(function(){angular.element(this).attr('disabled',newValue);});angular.element('div.wysiwyg-menu').find('select').each(function(){angular.element(this).attr('disabled',newValue);});});} +function configureBootstrapTitle(){if(attrs.enableBootstrapTitle==='true'&&attrs.enableBootstrapTitle!==undefined){element.find('button[title]').tooltip({container:'body'});}} +function insertTab(html,position){var begining=html.substr(0,position);var end=html.substr(position);return begining+' '+end;} +function configureListeners(){angular.element('.wysiwyg-menu').find('button').on('click',function(){var title=angular.element(this);scope.$emit('wysiwyg.click',title.attr('title')||title.attr('data-original-title'));});textarea.on('input keyup paste mouseup',function(){var html=textarea.html();if(html=='
'){html='';} +ngModelController.$setViewValue(html);});textarea.on('keydown',function(event){if(event.keyCode==9){var TAB_SPACES=4;var html=textarea.html();var selection=window.getSelection();var position=selection.anchorOffset;event.preventDefault();}});textarea.on('click keyup focus mouseup',function(){$timeout(function(){scope.isBold=scope.cmdState('bold');scope.isUnderlined=scope.cmdState('underline');scope.isStrikethrough=scope.cmdState('strikethrough');scope.isItalic=scope.cmdState('italic');scope.isSuperscript=itemIs('SUP');scope.isSubscript=itemIs('SUB');scope.isRightJustified=scope.cmdState('justifyright');scope.isLeftJustified=scope.cmdState('justifyleft');scope.isCenterJustified=scope.cmdState('justifycenter');scope.isPre=scope.cmdValue('formatblock')==='pre';scope.isBlockquote=scope.cmdValue('formatblock')==='blockquote';scope.isOrderedList=scope.cmdState('insertorderedlist');scope.isUnorderedList=scope.cmdState('insertunorderedlist');scope.fonts.forEach(function(v,k){if(scope.cmdValue('fontname').indexOf(v)>-1){scope.font=v;return false;}});scope.cmdValue('formatblock').toLowerCase();scope.formatBlocks.forEach(function(v,k){if(scope.cmdValue('formatblock').toLowerCase()===v.value.toLowerCase()){scope.formatBlock=v;return false;}});scope.fontSizes.forEach(function(v,k){if(scope.cmdValue('fontsize')===v.value){scope.fontSize=v;return false;}});scope.hiliteColor=getHiliteColor();element.find('button.wysiwyg-hiliteColor').css('background-color',scope.hiliteColor);scope.fontColor=scope.cmdValue('forecolor');element.find('button.wysiwyg-fontcolor').css('color',scope.fontColor);scope.isLink=itemIs('A');},0);});} +function itemIs(tag){var selection=window.getSelection().getRangeAt(0);if(selection){if(selection.startContainer.parentNode.tagName===tag.toUpperCase()||selection.endContainer.parentNode.tagName===tag.toUpperCase()){return true;}else{return false;}}else{return false;}} +function getHiliteColor(){var selection=window.getSelection().getRangeAt(0);if(selection){var style=angular.element(selection.startContainer.parentNode).attr('style');if(!angular.isDefined(style)) +return false;var a=style.split(';');for(var i=0;i