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 = "
" + "
" + "
" + output + "
" + "
"; // 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); }); } }; }]);