UNPKG

textangular

Version:

A radically powerful Text-Editor/Wysiwyg editor for Angular.js

176 lines (158 loc) 6.03 kB
// NOTE: textAngularVersion must match the Gruntfile.js 'setVersion' task.... and have format v/d+./d+./d+ var textAngularVersion = 'v1.5.8'; // This is automatically updated during the build process to the current release! // IE version detection - http://stackoverflow.com/questions/4169160/javascript-ie-detection-why-not-use-simple-conditional-comments // We need this as IE sometimes plays funny tricks with the contenteditable. // ---------------------------------------------------------- // If you're not in IE (or IE version is less than 5) then: // ie === undefined // If you're in IE (>=5) then you can determine which version: // ie === 7; // IE7 // Thus, to detect IE: // if (ie) {} // And to detect the version: // ie === 6 // IE6 // ie > 7 // IE8, IE9, IE10 ... // ie < 9 // Anything less than IE9 // ---------------------------------------------------------- /* istanbul ignore next: untestable browser check */ var _browserDetect = { ie: (function(){ var undef, v = 3, div = document.createElement('div'), all = div.getElementsByTagName('i'); while ( div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->', all[0] ); return v > 4 ? v : undef; }()), webkit: /AppleWebKit\/([\d.]+)/i.test(navigator.userAgent), isFirefox: navigator.userAgent.toLowerCase().indexOf('firefox') > -1 }; // Global to textAngular to measure performance where needed var performance = performance || {}; performance.now = (function() { return performance.now || performance.mozNow || performance.msNow || performance.oNow || performance.webkitNow || function() { return new Date().getTime(); }; })(); // usage is: // var t0 = performance.now(); // doSomething(); // var t1 = performance.now(); // console.log('Took', (t1 - t0).toFixed(4), 'milliseconds to do something!'); // // turn html into pure text that shows visiblity function stripHtmlToText(html) { var tmp = document.createElement("DIV"); tmp.innerHTML = html; var res = tmp.textContent || tmp.innerText || ''; res.replace('\u200B', ''); // zero width space res = res.trim(); return res; } // get html function getDomFromHtml(html) { var tmp = document.createElement("DIV"); tmp.innerHTML = html; return tmp; } // Global to textAngular REGEXP vars for block and list elements. var BLOCKELEMENTS = /^(address|article|aside|audio|blockquote|canvas|center|dd|div|dl|fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hgroup|hr|noscript|ol|output|p|pre|section|table|tfoot|ul|video)$/i; var LISTELEMENTS = /^(ul|li|ol)$/i; var VALIDELEMENTS = /^(address|article|aside|audio|blockquote|canvas|center|dd|div|dl|fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hgroup|hr|noscript|ol|output|p|pre|section|table|tfoot|ul|video|li)$/i; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Compatibility /* istanbul ignore next: trim shim for older browsers */ if (!String.prototype.trim) { String.prototype.trim = function () { return this.replace(/^\s+|\s+$/g, ''); }; } /* Custom stylesheet for the placeholders rules. Credit to: http://davidwalsh.name/add-rules-stylesheets */ var sheet, addCSSRule, removeCSSRule, _addCSSRule, _removeCSSRule, _getRuleIndex; /* istanbul ignore else: IE <8 test*/ if(_browserDetect.ie > 8 || _browserDetect.ie === undefined){ var _sheets = document.styleSheets; /* istanbul ignore next: preference for stylesheet loaded externally */ for(var i = 0; i < _sheets.length; i++){ if(_sheets[i].media.length === 0 || _sheets[i].media.mediaText.match(/(all|screen)/ig)){ if(_sheets[i].href){ if(_sheets[i].href.match(/textangular\.(min\.|)css/ig)){ sheet = _sheets[i]; break; } } } } /* istanbul ignore next: preference for stylesheet loaded externally */ if(!sheet){ // this sheet is used for the placeholders later on. sheet = (function() { // Create the <style> tag var style = document.createElement("style"); /* istanbul ignore else : WebKit hack :( */ if(_browserDetect.webkit) style.appendChild(document.createTextNode("")); // Add the <style> element to the page, add as first so the styles can be overridden by custom stylesheets document.getElementsByTagName('head')[0].appendChild(style); return style.sheet; })(); } // use as: addCSSRule("header", "float: left"); addCSSRule = function(selector, rules) { return _addCSSRule(sheet, selector, rules); }; _addCSSRule = function(_sheet, selector, rules){ var insertIndex; var insertedRule; // This order is important as IE 11 has both cssRules and rules but they have different lengths - cssRules is correct, rules gives an error in IE 11 /* istanbul ignore next: browser catches */ if(_sheet.cssRules) insertIndex = Math.max(_sheet.cssRules.length - 1, 0); else if(_sheet.rules) insertIndex = Math.max(_sheet.rules.length - 1, 0); /* istanbul ignore else: untestable IE option */ if(_sheet.insertRule) { _sheet.insertRule(selector + "{" + rules + "}", insertIndex); } else { _sheet.addRule(selector, rules, insertIndex); } /* istanbul ignore next: browser catches */ if(sheet.rules) insertedRule = sheet.rules[insertIndex]; else if(sheet.cssRules) insertedRule = sheet.cssRules[insertIndex]; // return the inserted stylesheet rule return insertedRule; }; _getRuleIndex = function(rule, rules) { var i, ruleIndex; for (i=0; i < rules.length; i++) { /* istanbul ignore else: check for correct rule */ if (rules[i].cssText === rule.cssText) { ruleIndex = i; break; } } return ruleIndex; }; removeCSSRule = function(rule){ _removeCSSRule(sheet, rule); }; /* istanbul ignore next: tests are browser specific */ _removeCSSRule = function(sheet, rule){ var rules = sheet.cssRules || sheet.rules; if(!rules || rules.length === 0) return; var ruleIndex = _getRuleIndex(rule, rules); if(sheet.removeRule){ sheet.removeRule(ruleIndex); }else{ sheet.deleteRule(ruleIndex); } }; }