Skip to content

Commit

Permalink
Merge cccaada into 437afb0
Browse files Browse the repository at this point in the history
  • Loading branch information
schup committed Jun 16, 2014
2 parents 437afb0 + cccaada commit e1812e7
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 15 deletions.
9 changes: 8 additions & 1 deletion src/textAngular.js
Expand Up @@ -195,12 +195,14 @@ See README.md or https://github.com/fraywing/textAngular/wiki for requirements a
restoreSelection is only defined if the rangy library is included and it can be called as `restoreSelection()` to restore the users
selection in the WYSIWYG editor.
display: [string]?
Optional, an HTML element to be displayed as the buton. The `scope` of the button is the tool definition object with some additional functions
Optional, an HTML element to be displayed as the button. The `scope` of the button is the tool definition object with some additional functions
If set this will cause buttontext and iconclass to be ignored
buttontext: [string]?
if this is defined it will replace the contents of the element contained in the `display` element
iconclass: [string]?
if this is defined an icon (<i>) will be appended to the `display` element with this string as it's class
tooltiptext: [string]?
Optional, a plain text description of the action, used for the title attribute of the action button in the toolbar by default.
activestate: [function(commonElement)]?
this function is called on every caret movement, if it returns true then the class taOptions.classes.toolbarButtonActive
will be applied to the `display` element, else the class will be removed
Expand Down Expand Up @@ -1363,6 +1365,11 @@ See README.md or https://github.com/fraywing/textAngular/wiki for requirements a
toolElement.attr('tabindex', '-1');
toolElement.attr('ng-click', 'executeAction()');
toolElement.attr('ng-class', 'displayActiveToolClass(active)');

if (toolDefinition && toolDefinition.tooltiptext) {
toolElement.attr('title', toolDefinition.tooltiptext);
}

toolElement.on('mousedown', function(e, eventData){
/* istanbul ignore else: this is for catching the jqLite testing*/
if(eventData) angular.extend(e, eventData);
Expand Down
114 changes: 103 additions & 11 deletions src/textAngularSetup.js
Expand Up @@ -78,15 +78,88 @@ textAngularSetup.value('taCustomRenderers', [
]);

textAngularSetup.constant('taTranslations', {
toggleHTML: "Toggle HTML",
insertImage: "Please enter a image URL to insert",
insertLink: "Please enter a URL to insert",
insertVideo: "Please enter a youtube URL to embed"
// moved to sub-elements
//toggleHTML: "Toggle HTML",
//insertImage: "Please enter a image URL to insert",
//insertLink: "Please enter a URL to insert",
//insertVideo: "Please enter a youtube URL to embed",
html: {
buttontext: 'Toggle HTML',
tooltip: 'Toggle html / Rich Text'
},
// tooltip for heading - might be worth splitting
heading: {
tooltip: 'Heading '
},
p: {
tooltip: 'Paragraph'
},
pre: {
tooltip: 'Preformatted text'
},
ul: {
tooltip: 'Unordered List'
},
ol: {
tooltip: 'Ordered List'
},
quote: {
tooltip: 'Quote/unqoute selection or paragraph'
},
undo: {
tooltip: 'Undo'
},
redo: {
tooltip: 'Redo'
},
bold: {
tooltip: 'Bold'
},
italic: {
tooltip: 'Italic'
},
underline: {
tooltip: 'Underline'
},
justifyLeft: {
tooltip: 'Align text left'
},
justifyRight: {
tooltip: 'Align text right'
},
justifyCenter: {
tooltip: 'Center'
},
indent: {
tooltip: 'Increase indent'
},
outdent: {
tooltip: 'Decrease indent'
},
clear: {
tooltip: 'Clear formatting'
},
insertImage: {
dialogPrompt: 'Please enter a image URL to insert',
tooltip: 'Insert image',
hotkey: 'the - possibly language dependent hotkey ... for some future implementation'
},
insertVideo: {
tooltip: 'Insert video',
dialogPrompt: 'Please enter a youtube URL to embed'
},
insertLink: {
tooltip: 'Insert / edit link',
dialogPrompt: "Please enter a URL to insert"
}


});

textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelection', function(taRegisterTool, $window, taTranslations, taSelection){
taRegisterTool("html", {
buttontext: taTranslations.toggleHTML,
buttontext: taTranslations.html.buttontext,
tooltiptext: taTranslations.html.tooltip,
action: function(){
this.$editor().switchView();
},
Expand All @@ -105,59 +178,69 @@ textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelectio
angular.forEach(['h1','h2','h3','h4','h5','h6'], function(h){
taRegisterTool(h.toLowerCase(), {
buttontext: h.toUpperCase(),
tooltiptext: taTranslations.heading.tooltip + h.charAt(1),
action: headerAction,
activeState: _retActiveStateFunction(h.toLowerCase())
});
});
taRegisterTool('p', {
buttontext: 'P',
tooltiptext: taTranslations.p.tooltip,
action: function(){
return this.$editor().wrapSelection("formatBlock", "<P>");
},
activeState: function(){ return this.$editor().queryFormatBlockState('p'); }
});
// key: pre -> taTranslations[key].tooltip, taTranslations[key].buttontext
taRegisterTool('pre', {
buttontext: 'pre',
tooltiptext: taTranslations.pre.tooltip,
action: function(){
return this.$editor().wrapSelection("formatBlock", "<PRE>");
},
activeState: function(){ return this.$editor().queryFormatBlockState('pre'); }
});
taRegisterTool('ul', {
iconclass: 'fa fa-list-ul',
tooltiptext: taTranslations.ul.tooltip,
action: function(){
return this.$editor().wrapSelection("insertUnorderedList", null);
},
activeState: function(){ return document.queryCommandState('insertUnorderedList'); }
});
taRegisterTool('ol', {
iconclass: 'fa fa-list-ol',
tooltiptext: taTranslations.ol.tooltip,
action: function(){
return this.$editor().wrapSelection("insertOrderedList", null);
},
activeState: function(){ return document.queryCommandState('insertOrderedList'); }
});
taRegisterTool('quote', {
iconclass: 'fa fa-quote-right',
tooltiptext: taTranslations.quote.tooltip,
action: function(){
return this.$editor().wrapSelection("formatBlock", "<BLOCKQUOTE>");
},
activeState: function(){ return this.$editor().queryFormatBlockState('blockquote'); }
});
taRegisterTool('undo', {
iconclass: 'fa fa-undo',
tooltiptext: taTranslations.undo.tooltip,
action: function(){
return this.$editor().wrapSelection("undo", null);
}
});
taRegisterTool('redo', {
iconclass: 'fa fa-repeat',
tooltiptext: taTranslations.redo.tooltip,
action: function(){
return this.$editor().wrapSelection("redo", null);
}
});
taRegisterTool('bold', {
iconclass: 'fa fa-bold',
tooltiptext: taTranslations.bold.tooltip,
action: function(){
return this.$editor().wrapSelection("bold", null);
},
Expand All @@ -168,6 +251,7 @@ textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelectio
});
taRegisterTool('justifyLeft', {
iconclass: 'fa fa-align-left',
tooltiptext: taTranslations.justifyLeft.tooltip,
action: function(){
return this.$editor().wrapSelection("justifyLeft", null);
},
Expand All @@ -181,6 +265,7 @@ textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelectio
});
taRegisterTool('justifyRight', {
iconclass: 'fa fa-align-right',
tooltiptext: taTranslations.justifyRight.tooltip,
action: function(){
return this.$editor().wrapSelection("justifyRight", null);
},
Expand All @@ -193,6 +278,7 @@ textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelectio
});
taRegisterTool('justifyCenter', {
iconclass: 'fa fa-align-center',
tooltiptext: taTranslations.justifyCenter.tooltip,
action: function(){
return this.$editor().wrapSelection("justifyCenter", null);
},
Expand All @@ -205,7 +291,7 @@ textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelectio
});
taRegisterTool('indent', {
iconclass: 'fa fa-indent',
tooltiptext: 'Indent',
tooltiptext: taTranslations.indent.tooltip,
action: function(){
return this.$editor().wrapSelection("indent", null);
},
Expand All @@ -215,7 +301,7 @@ textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelectio
});
taRegisterTool('outdent', {
iconclass: 'fa fa-outdent',
tooltiptext: 'Outdent',
tooltiptext: taTranslations.outdent.tooltip,
action: function(){
return this.$editor().wrapSelection("outdent", null);
},
Expand All @@ -225,6 +311,7 @@ textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelectio
});
taRegisterTool('italics', {
iconclass: 'fa fa-italic',
tooltiptext: taTranslations.italic.tooltip,
action: function(){
return this.$editor().wrapSelection("italic", null);
},
Expand All @@ -235,6 +322,7 @@ textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelectio
});
taRegisterTool('underline', {
iconclass: 'fa fa-underline',
tooltiptext: taTranslations.underline.tooltip,
action: function(){
return this.$editor().wrapSelection("underline", null);
},
Expand All @@ -245,6 +333,7 @@ textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelectio
});
taRegisterTool('clear', {
iconclass: 'fa fa-ban',
tooltiptext: taTranslations.clear.tooltip,
action: function(deferred, restoreSelection){
this.$editor().wrapSelection("removeFormat", null);
var possibleNodes = angular.element(taSelection.getSelectionElement());
Expand Down Expand Up @@ -372,9 +461,10 @@ textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelectio

taRegisterTool('insertImage', {
iconclass: 'fa fa-picture-o',
tooltiptext: taTranslations.insertImage.tooltip,
action: function(){
var imageLink;
imageLink = $window.prompt(taTranslations.insertImage, 'http://');
imageLink = $window.prompt(taTranslations.insertImage.dialogPrompt, 'http://');
if(imageLink && imageLink !== '' && imageLink !== 'http://'){
return this.$editor().wrapSelection('insertImage', imageLink, true);
}
Expand All @@ -386,9 +476,10 @@ textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelectio
});
taRegisterTool('insertVideo', {
iconclass: 'fa fa-youtube-play',
tooltiptext: taTranslations.insertVideo.tooltip,
action: function(){
var urlPrompt;
urlPrompt = $window.prompt(taTranslations.insertVideo, 'http://');
urlPrompt = $window.prompt(taTranslations.insertVideo.dialogPrompt, 'http://');
if (urlPrompt && urlPrompt !== '' && urlPrompt !== 'http://') {
// get the video ID
var ids = urlPrompt.match(/(\?|&)v=[^&]*/);
Expand All @@ -410,10 +501,11 @@ textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelectio
}
});
taRegisterTool('insertLink', {
tooltiptext: taTranslations.insertLink.tooltip,
iconclass: 'fa fa-link',
action: function(){
var urlLink;
urlLink = $window.prompt(taTranslations.insertLink, 'http://');
urlLink = $window.prompt(taTranslations.insertLink.dialogPrompt, 'http://');
if(urlLink && urlLink !== '' && urlLink !== 'http://'){
return this.$editor().wrapSelection('createLink', urlLink, true);
}
Expand Down Expand Up @@ -446,7 +538,7 @@ textAngularSetup.run(['taRegisterTool', '$window', 'taTranslations', 'taSelectio
var reLinkButton = angular.element('<button type="button" class="btn btn-default btn-sm btn-small" tabindex="-1" unselectable="on"><i class="fa fa-edit icon-edit"></i></button>');
reLinkButton.on('click', function(event){
event.preventDefault();
var urlLink = $window.prompt(taTranslations.insertLink, $element.attr('href'));
var urlLink = $window.prompt(taTranslations.insertLink.dialogPrompt, $element.attr('href'));
if(urlLink && urlLink !== '' && urlLink !== 'http://'){
$element.attr('href', urlLink);
editorScope.updateTaBindtaTextElement();
Expand Down
34 changes: 31 additions & 3 deletions test/taTools.spec.js
Expand Up @@ -94,6 +94,10 @@ describe('taTools test tool actions', function(){
$rootScope.$digest();
return button;
};

var findButton = function(name){
return buttonByName(element, name);
};

// We use an assumption here and only test whether the button reports as being activated
// it ended up being too difficult to reselect and un-apply
Expand Down Expand Up @@ -207,6 +211,29 @@ describe('taTools test tool actions', function(){
expect(jQuery('.ta-text').is(":visible"));
expect(jQuery('.ta-text').is(":focus"));
}));

it('html button should have title attribute', function() {
expect(findButton('h1').attr('title')).toBe('Heading 1');
expect(findButton('h2').attr('title')).toBe('Heading 2');
expect(findButton('h3').attr('title')).toBe('Heading 3');
expect(findButton('h4').attr('title')).toBe('Heading 4');
expect(findButton('h5').attr('title')).toBe('Heading 5');
expect(findButton('h6').attr('title')).toBe('Heading 6');

expect(findButton('justifyLeft').attr('title')).toBe('Align text left');
expect(findButton('justifyCenter').attr('title')).toBe('Center');
expect(findButton('justifyRight').attr('title')).toBe('Align text right');

expect(findButton('indent').attr('title')).toBe('Increase indent');
expect(findButton('outdent').attr('title')).toBe('Decrease indent');

expect(findButton('insertImage').attr('title')).toBe('Insert image');
expect(findButton('html').attr('title')).toBe('Toggle html / Rich Text');
expect(findButton('insertVideo').attr('title')).toBe('Insert video');
expect(findButton('insertLink').attr('title')).toBe('Insert / edit link');


});

describe('check untestables don\'t error - ', function(){
it('redo', function(){
Expand Down Expand Up @@ -460,7 +487,8 @@ describe('taTools test tool actions', function(){
editorScope.displayElements.popoverContainer.find('button').eq(0).triggerHandler('click');
$rootScope.$digest();
val = editorScope.displayElements.text.find('p').find('img').css('width');
if(jQuery === angular.element) expect(val === '345px' || val === '344px').toBe(true);
// got some variation in size - dependent on phantomjs version / platform?
if(jQuery === angular.element) expect(val === '345px' || val === '344px' || val === '343px').toBe(true);
else expect(val).toBe('100%');
});

Expand All @@ -469,7 +497,7 @@ describe('taTools test tool actions', function(){
editorScope.displayElements.popoverContainer.find('button').eq(1).triggerHandler('click');
$rootScope.$digest();
val = editorScope.displayElements.text.find('p').find('img').css('width');
if(jQuery === angular.element) expect(val).toBe('172px');
if(jQuery === angular.element) expect(val === '172px' || val === '171px').toBe(true);
else expect(val).toBe('50%');
});

Expand All @@ -478,7 +506,7 @@ describe('taTools test tool actions', function(){
editorScope.displayElements.popoverContainer.find('button').eq(2).triggerHandler('click');
$rootScope.$digest();
val = editorScope.displayElements.text.find('p').find('img').css('width');
if(jQuery === angular.element) expect(val).toBe('86px');
if(jQuery === angular.element) expect(val === '86px' || val === '85px').toBe(true);
else expect(val).toBe('25%');
});

Expand Down

0 comments on commit e1812e7

Please sign in to comment.