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
diff --git a/dist/angular-wysiwyg.js b/dist/angular-wysiwyg.js
index 09523f5..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,1051 +24,983 @@ 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: '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.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..952e83a 100644
--- a/dist/angular-wysiwyg.min.js
+++ b/dist/angular-wysiwyg.min.js
@@ -1 +1,29 @@
-!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'+''+''+''+'',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