browser.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*globals $, svgedit*/
  2. /*jslint vars: true, eqeq: true*/
  3. /**
  4. * Package: svgedit.browser
  5. *
  6. * Licensed under the MIT License
  7. *
  8. * Copyright(c) 2010 Jeff Schiller
  9. * Copyright(c) 2010 Alexis Deveria
  10. */
  11. // Dependencies:
  12. // 1) jQuery (for $.alert())
  13. (function() {'use strict';
  14. if (!svgedit.browser) {
  15. svgedit.browser = {};
  16. }
  17. // alias
  18. var NS = svgedit.NS;
  19. var supportsSvg_ = (function() {
  20. return !!document.createElementNS && !!document.createElementNS(NS.SVG, 'svg').createSVGRect;
  21. }());
  22. svgedit.browser.supportsSvg = function() { return supportsSvg_; };
  23. if(!svgedit.browser.supportsSvg()) {
  24. window.location = 'browser-not-supported.html';
  25. return;
  26. }
  27. var userAgent = navigator.userAgent;
  28. var svg = document.createElementNS(NS.SVG, 'svg');
  29. // Note: Browser sniffing should only be used if no other detection method is possible
  30. var isOpera_ = !!window.opera;
  31. var isWebkit_ = userAgent.indexOf('AppleWebKit') >= 0;
  32. var isGecko_ = userAgent.indexOf('Gecko/') >= 0;
  33. var isIE_ = userAgent.indexOf('MSIE') >= 0;
  34. var isChrome_ = userAgent.indexOf('Chrome/') >= 0;
  35. var isWindows_ = userAgent.indexOf('Windows') >= 0;
  36. var isMac_ = userAgent.indexOf('Macintosh') >= 0;
  37. var isTouch_ = 'ontouchstart' in window;
  38. var supportsSelectors_ = (function() {
  39. return !!svg.querySelector;
  40. }());
  41. var supportsXpath_ = (function() {
  42. return !!document.evaluate;
  43. }());
  44. // segList functions (for FF1.5 and 2.0)
  45. var supportsPathReplaceItem_ = (function() {
  46. var path = document.createElementNS(NS.SVG, 'path');
  47. path.setAttribute('d', 'M0,0 10,10');
  48. var seglist = path.pathSegList;
  49. var seg = path.createSVGPathSegLinetoAbs(5,5);
  50. try {
  51. seglist.replaceItem(seg, 0);
  52. return true;
  53. } catch(err) {}
  54. return false;
  55. }());
  56. var supportsPathInsertItemBefore_ = (function() {
  57. var path = document.createElementNS(NS.SVG, 'path');
  58. path.setAttribute('d', 'M0,0 10,10');
  59. var seglist = path.pathSegList;
  60. var seg = path.createSVGPathSegLinetoAbs(5,5);
  61. try {
  62. seglist.insertItemBefore(seg, 0);
  63. return true;
  64. } catch(err) {}
  65. return false;
  66. }());
  67. // text character positioning (for IE9)
  68. var supportsGoodTextCharPos_ = (function() {
  69. var svgroot = document.createElementNS(NS.SVG, 'svg');
  70. var svgcontent = document.createElementNS(NS.SVG, 'svg');
  71. document.documentElement.appendChild(svgroot);
  72. svgcontent.setAttribute('x', 5);
  73. svgroot.appendChild(svgcontent);
  74. var text = document.createElementNS(NS.SVG, 'text');
  75. text.textContent = 'a';
  76. svgcontent.appendChild(text);
  77. var pos = text.getStartPositionOfChar(0).x;
  78. document.documentElement.removeChild(svgroot);
  79. return (pos === 0);
  80. }());
  81. var supportsPathBBox_ = (function() {
  82. var svgcontent = document.createElementNS(NS.SVG, 'svg');
  83. document.documentElement.appendChild(svgcontent);
  84. var path = document.createElementNS(NS.SVG, 'path');
  85. path.setAttribute('d', 'M0,0 C0,0 10,10 10,0');
  86. svgcontent.appendChild(path);
  87. var bbox = path.getBBox();
  88. document.documentElement.removeChild(svgcontent);
  89. return (bbox.height > 4 && bbox.height < 5);
  90. }());
  91. // Support for correct bbox sizing on groups with horizontal/vertical lines
  92. var supportsHVLineContainerBBox_ = (function() {
  93. var svgcontent = document.createElementNS(NS.SVG, 'svg');
  94. document.documentElement.appendChild(svgcontent);
  95. var path = document.createElementNS(NS.SVG, 'path');
  96. path.setAttribute('d', 'M0,0 10,0');
  97. var path2 = document.createElementNS(NS.SVG, 'path');
  98. path2.setAttribute('d', 'M5,0 15,0');
  99. var g = document.createElementNS(NS.SVG, 'g');
  100. g.appendChild(path);
  101. g.appendChild(path2);
  102. svgcontent.appendChild(g);
  103. var bbox = g.getBBox();
  104. document.documentElement.removeChild(svgcontent);
  105. // Webkit gives 0, FF gives 10, Opera (correctly) gives 15
  106. return (bbox.width == 15);
  107. }());
  108. var supportsEditableText_ = (function() {
  109. // TODO: Find better way to check support for this
  110. return isOpera_;
  111. }());
  112. var supportsGoodDecimals_ = (function() {
  113. // Correct decimals on clone attributes (Opera < 10.5/win/non-en)
  114. var rect = document.createElementNS(NS.SVG, 'rect');
  115. rect.setAttribute('x', 0.1);
  116. var crect = rect.cloneNode(false);
  117. var retValue = (crect.getAttribute('x').indexOf(',') == -1);
  118. if(!retValue) {
  119. $.alert('NOTE: This version of Opera is known to contain bugs in SVG-edit.\n'+
  120. 'Please upgrade to the <a href="http://opera.com">latest version</a> in which the problems have been fixed.');
  121. }
  122. return retValue;
  123. }());
  124. var supportsNonScalingStroke_ = (function() {
  125. var rect = document.createElementNS(NS.SVG, 'rect');
  126. rect.setAttribute('style', 'vector-effect:non-scaling-stroke');
  127. return rect.style.vectorEffect === 'non-scaling-stroke';
  128. }());
  129. var supportsNativeSVGTransformLists_ = (function() {
  130. var rect = document.createElementNS(NS.SVG, 'rect');
  131. var rxform = rect.transform.baseVal;
  132. var t1 = svg.createSVGTransform();
  133. rxform.appendItem(t1);
  134. return rxform.getItem(0) == t1;
  135. }());
  136. // Public API
  137. svgedit.browser.isOpera = function() { return isOpera_; };
  138. svgedit.browser.isWebkit = function() { return isWebkit_; };
  139. svgedit.browser.isGecko = function() { return isGecko_; };
  140. svgedit.browser.isIE = function() { return isIE_; };
  141. svgedit.browser.isChrome = function() { return isChrome_; };
  142. svgedit.browser.isWindows = function() { return isWindows_; };
  143. svgedit.browser.isMac = function() { return isMac_; };
  144. svgedit.browser.isTouch = function() { return isTouch_; };
  145. svgedit.browser.supportsSelectors = function() { return supportsSelectors_; };
  146. svgedit.browser.supportsXpath = function() { return supportsXpath_; };
  147. svgedit.browser.supportsPathReplaceItem = function() { return supportsPathReplaceItem_; };
  148. svgedit.browser.supportsPathInsertItemBefore = function() { return supportsPathInsertItemBefore_; };
  149. svgedit.browser.supportsPathBBox = function() { return supportsPathBBox_; };
  150. svgedit.browser.supportsHVLineContainerBBox = function() { return supportsHVLineContainerBBox_; };
  151. svgedit.browser.supportsGoodTextCharPos = function() { return supportsGoodTextCharPos_; };
  152. svgedit.browser.supportsEditableText = function() { return supportsEditableText_; };
  153. svgedit.browser.supportsGoodDecimals = function() { return supportsGoodDecimals_; };
  154. svgedit.browser.supportsNonScalingStroke = function() { return supportsNonScalingStroke_; };
  155. svgedit.browser.supportsNativeTransformLists = function() { return supportsNativeSVGTransformLists_; };
  156. }());