angular.module('kalgudiApp').directive('converthtml',
["$rootScope", "$state", "$sce", "$compile",
function ($rootScope, $state, $sce, $compile) {
return {
template: "
",
scope: {
converthtml: "=converthtml",
richText: "=richText",
shareId: "=shareId"
},
restrict: 'A',
link: function (scope, element, attrs) {
/**
* Flag to toggle long content truncation.
*/
scope.showMore = false;
/**
* Flag to toggle show more button.
*/
scope.isShowMoreRequired = false;
/**
* Constant word limit for normal text truncation
*/
const WORD_LIMIT = 40;
/**
* Maximum height of share text.
*/
const MAX_HEIGHT = 36;
/**
* Event subscriber, watch for change in convertHtml field.
*/
scope.$watch('converthtml', convertSimpleText);
/**
* Event subscriber, watch for change in richText field.
*/
scope.$watch('richText', convertRichText);
/**
* Since directives cannot access rootScope functions
* directly. Hence, link reference of openExternalLink()
* function within scope.
*/
scope.openExternalLink = $rootScope.openExternalLink;
/**
* Toggles show more and show less feature.
*/
scope.toggleShow = function () {
scope.showMore = !scope.showMore;
};
/**
* This function executes for all rich texts and verifies whether
* show more toggle is required or not.
*
* The core logic to check show more is verify actual height the
* share content and if it exceeds MAX_HEIGHT then show more is
* required.
*/
scope.checkShowMore = function () {
var expr = "#" + scope.shareId + " .hide-overflow";
var height = $(expr).height();
scope.isShowMoreRequired = (height > MAX_HEIGHT);
}
/**
* It converts normal share texts URL in clickable links.
* It also adds function to show or hide share text contents, if
* it exceeds WORD_LIMIT.
*
* Use this function to for simple text to html conversion.
*
* @see convertRichText
*/
function convertSimpleText() {
// Do nothing for rich texts
if (scope.richText) return;
// Don't convert it as a simple text if it contains html tags.
// Also if richText field contains text.
var regex = /(<([^>]+)>)/ig
if (regex.test(scope.converthtml) && !scope.richText)
return convertRichText(scope.converthtml);
// Replace textual links to clickable link tags.
var text = replaceURLWithHTMLLinks(scope.converthtml);
// List of state, where we don't need text truncation
var showFullTextForPages = ['questionfullview', 'shareAThoughtfullview'];
// Do not truncate HTML for postFullView and mobile shares full view.
if (text && text.split(" ").length > WORD_LIMIT &&
$state.current.name != "myconnects.postFullView" &&
!showFullTextForPages.includes($state.current.data.action) ) {
var action_test = applyTruncation(WORD_LIMIT, text);
scope.convertedText = $sce.trustAsHtml(action_test);
} else {
scope.convertedText = $sce.trustAsHtml(text);
}
}
/**
* Rich texts are already converted in html clickable link format.
* It only adds function to show or hide rich text contents to a
* specified height.
*
* @text Pass string if conversion should override richText field
* with this.
*
* @see convertSimpleText()
*/
function convertRichText(text) {
var text = text || scope.richText;
// Null checks
if (!text) return;
var output = "";
// Break text into words and
// convert simple unclickable links to clickable links
text.split(' ').forEach(function(word) {
output += replaceURLWithHTMLLinks(word) + " ";
});
var richTextTemplate =
"" +
"
";
// Append show more and show less for desktop devices only.
if (!IS_MOBILE_DEVICE) {
richTextTemplate +=
"
" +
"" +
" " + "show more" +
"" +
"" +
"" +
" " + "show less" +
"" +
"" +
"
";
}
richTextTemplate +=
"
";
scope.convertedText = $sce.trustAsHtml(richTextTemplate);
}
/**
* Replaces normal string representations of links to clickable links.
* It uses a regex to find and wraps all link inside an anchor tag.
*
* @text Text to convert.
*
* @return Returns html string.
*/
function replaceURLWithHTMLLinks(text) {
// Null and rich HTML check
if (text && (text.includes('$1");
else
return text.replace(exp, "$1");
} else return text;
}
/**
* Truncates normal text based on WORD_LIMIT. Calling this function
* adds show more and show less clickable links that shows and hides
* text if it exceeds WORD_LIMIT.
*
* @WORD_LIMIT Maximum limit of words to apply truncation.
* @text Text to convert.
*
* @returns Returns truncated html string.
*/
function applyTruncation(WORD_LIMIT, text) {
var splitText = text.split(" ");
var final_obj =
"" +
splitText.slice(0, WORD_LIMIT).join(" ") + " " +
"... ";
// Append show more and show less for desktop devices
if (!IS_MOBILE_DEVICE) {
final_obj +=
"" +
"show more" +
"" +
"" +
splitText.slice(WORD_LIMIT, splitText.length).join(" ") +
" " +
"" +
"show less" +
"" +
"";
}
final_obj += "";
return final_obj;
}
}
}
}]);
// Need scope inside binding ng-bind-html don't watch scope
angular.module('kalgudiApp').directive('bindHtmlCompile', ['$compile', function ($compile) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
scope.$watch(function () {
return scope.$eval(attrs.bindHtmlCompile);
}, function (value) {
element.html(value);
$compile(element.contents())(scope);
});
}
};
}]);