globals.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // IE version detection - http://stackoverflow.com/questions/4169160/javascript-ie-detection-why-not-use-simple-conditional-comments
  2. // We need this as IE sometimes plays funny tricks with the contenteditable.
  3. // ----------------------------------------------------------
  4. // If you're not in IE (or IE version is less than 5) then:
  5. // ie === undefined
  6. // If you're in IE (>=5) then you can determine which version:
  7. // ie === 7; // IE7
  8. // Thus, to detect IE:
  9. // if (ie) {}
  10. // And to detect the version:
  11. // ie === 6 // IE6
  12. // ie > 7 // IE8, IE9, IE10 ...
  13. // ie < 9 // Anything less than IE9
  14. // ----------------------------------------------------------
  15. /* istanbul ignore next: untestable browser check */
  16. var _browserDetect = {
  17. ie: (function(){
  18. var undef,
  19. v = 3,
  20. div = document.createElement('div'),
  21. all = div.getElementsByTagName('i');
  22. while (
  23. div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
  24. all[0]
  25. );
  26. return v > 4 ? v : undef;
  27. }()),
  28. webkit: /AppleWebKit\/([\d.]+)/i.test(navigator.userAgent)
  29. };
  30. // fix a webkit bug, see: https://gist.github.com/shimondoodkin/1081133
  31. // this is set true when a blur occurs as the blur of the ta-bind triggers before the click
  32. var globalContentEditableBlur = false;
  33. /* istanbul ignore next: Browser Un-Focus fix for webkit */
  34. if(_browserDetect.webkit) {
  35. document.addEventListener("mousedown", function(_event){
  36. var e = _event || window.event;
  37. var curelement = e.target;
  38. if(globalContentEditableBlur && curelement !== null){
  39. var isEditable = false;
  40. var tempEl = curelement;
  41. while(tempEl !== null && tempEl.tagName.toLowerCase() !== 'html' && !isEditable){
  42. isEditable = tempEl.contentEditable === 'true';
  43. tempEl = tempEl.parentNode;
  44. }
  45. if(!isEditable){
  46. document.getElementById('textAngular-editableFix-010203040506070809').setSelectionRange(0, 0); // set caret focus to an element that handles caret focus correctly.
  47. curelement.focus(); // focus the wanted element.
  48. if (curelement.select) {
  49. curelement.select(); // use select to place cursor for input elements.
  50. }
  51. }
  52. }
  53. globalContentEditableBlur = false;
  54. }, false); // add global click handler
  55. angular.element(document).ready(function () {
  56. angular.element(document.body).append(angular.element('<input id="textAngular-editableFix-010203040506070809" class="ta-hidden-input" aria-hidden="true" unselectable="on" tabIndex="-1">'));
  57. });
  58. }
  59. // Gloabl to textAngular REGEXP vars for block and list elements.
  60. var BLOCKELEMENTS = /^(address|article|aside|audio|blockquote|canvas|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;
  61. var LISTELEMENTS = /^(ul|li|ol)$/i;
  62. var VALIDELEMENTS = /^(address|article|aside|audio|blockquote|canvas|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;
  63. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Compatibility
  64. /* istanbul ignore next: trim shim for older browsers */
  65. if (!String.prototype.trim) {
  66. String.prototype.trim = function () {
  67. return this.replace(/^\s+|\s+$/g, '');
  68. };
  69. }
  70. /*
  71. Custom stylesheet for the placeholders rules.
  72. Credit to: http://davidwalsh.name/add-rules-stylesheets
  73. */
  74. var sheet, addCSSRule, removeCSSRule, _addCSSRule, _removeCSSRule, _getRuleIndex;
  75. /* istanbul ignore else: IE <8 test*/
  76. if(_browserDetect.ie > 8 || _browserDetect.ie === undefined){
  77. var _sheets = document.styleSheets;
  78. /* istanbul ignore next: preference for stylesheet loaded externally */
  79. for(var i = 0; i < _sheets.length; i++){
  80. if(_sheets[i].media.length === 0 || _sheets[i].media.mediaText.match(/(all|screen)/ig)){
  81. if(_sheets[i].href){
  82. if(_sheets[i].href.match(/textangular\.(min\.|)css/ig)){
  83. sheet = _sheets[i];
  84. break;
  85. }
  86. }
  87. }
  88. }
  89. /* istanbul ignore next: preference for stylesheet loaded externally */
  90. if(!sheet){
  91. // this sheet is used for the placeholders later on.
  92. sheet = (function() {
  93. // Create the <style> tag
  94. var style = document.createElement("style");
  95. /* istanbul ignore else : WebKit hack :( */
  96. if(_browserDetect.webkit) style.appendChild(document.createTextNode(""));
  97. // Add the <style> element to the page, add as first so the styles can be overridden by custom stylesheets
  98. document.getElementsByTagName('head')[0].appendChild(style);
  99. return style.sheet;
  100. })();
  101. }
  102. // use as: addCSSRule("header", "float: left");
  103. addCSSRule = function(selector, rules) {
  104. return _addCSSRule(sheet, selector, rules);
  105. };
  106. _addCSSRule = function(_sheet, selector, rules){
  107. var insertIndex;
  108. var insertedRule;
  109. // 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
  110. /* istanbul ignore next: browser catches */
  111. if(_sheet.cssRules) insertIndex = Math.max(_sheet.cssRules.length - 1, 0);
  112. else if(_sheet.rules) insertIndex = Math.max(_sheet.rules.length - 1, 0);
  113. /* istanbul ignore else: untestable IE option */
  114. if(_sheet.insertRule) {
  115. _sheet.insertRule(selector + "{" + rules + "}", insertIndex);
  116. }
  117. else {
  118. _sheet.addRule(selector, rules, insertIndex);
  119. }
  120. /* istanbul ignore next: browser catches */
  121. if(sheet.rules) insertedRule = sheet.rules[insertIndex];
  122. else if(sheet.cssRules) insertedRule = sheet.cssRules[insertIndex];
  123. // return the inserted stylesheet rule
  124. return insertedRule;
  125. };
  126. _getRuleIndex = function(rule, rules) {
  127. var i, ruleIndex;
  128. for (i=0; i < rules.length; i++) {
  129. /* istanbul ignore else: check for correct rule */
  130. if (rules[i].cssText === rule.cssText) {
  131. ruleIndex = i;
  132. break;
  133. }
  134. }
  135. return ruleIndex;
  136. };
  137. removeCSSRule = function(rule){
  138. _removeCSSRule(sheet, rule);
  139. };
  140. /* istanbul ignore next: tests are browser specific */
  141. _removeCSSRule = function(sheet, rule){
  142. var rules = sheet.cssRules || sheet.rules;
  143. if(!rules || rules.length === 0) return;
  144. var ruleIndex = _getRuleIndex(rule, rules);
  145. if(sheet.removeRule){
  146. sheet.removeRule(ruleIndex);
  147. }else{
  148. sheet.deleteRule(ruleIndex);
  149. }
  150. };
  151. }