util.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /**
  2. * Extend object a with the properties of object b.
  3. * If there's a conflict, object b takes precedence.
  4. *
  5. * @param {object} a
  6. * @param {object} b
  7. */
  8. export const extend = ( a, b ) => {
  9. for( let i in b ) {
  10. a[ i ] = b[ i ];
  11. }
  12. return a;
  13. }
  14. /**
  15. * Converts the target object to an array.
  16. *
  17. * @param {object} o
  18. * @return {object[]}
  19. */
  20. export const toArray = ( o ) => {
  21. return Array.prototype.slice.call( o );
  22. }
  23. /**
  24. * Utility for deserializing a value.
  25. *
  26. * @param {*} value
  27. * @return {*}
  28. */
  29. export const deserialize = ( value ) => {
  30. if( typeof value === 'string' ) {
  31. if( value === 'null' ) return null;
  32. else if( value === 'true' ) return true;
  33. else if( value === 'false' ) return false;
  34. else if( value.match( /^-?[\d\.]+$/ ) ) return parseFloat( value );
  35. }
  36. return value;
  37. }
  38. /**
  39. * Measures the distance in pixels between point a
  40. * and point b.
  41. *
  42. * @param {object} a point with x/y properties
  43. * @param {object} b point with x/y properties
  44. *
  45. * @return {number}
  46. */
  47. export const distanceBetween = ( a, b ) => {
  48. let dx = a.x - b.x,
  49. dy = a.y - b.y;
  50. return Math.sqrt( dx*dx + dy*dy );
  51. }
  52. /**
  53. * Applies a CSS transform to the target element.
  54. *
  55. * @param {HTMLElement} element
  56. * @param {string} transform
  57. */
  58. export const transformElement = ( element, transform ) => {
  59. element.style.transform = transform;
  60. }
  61. /**
  62. * Find the closest parent that matches the given
  63. * selector.
  64. *
  65. * @param {HTMLElement} target The child element
  66. * @param {String} selector The CSS selector to match
  67. * the parents against
  68. *
  69. * @return {HTMLElement} The matched parent or null
  70. * if no matching parent was found
  71. */
  72. export const closestParent = ( target, selector ) => {
  73. let parent = target.parentNode;
  74. while( parent ) {
  75. // There's some overhead doing this each time, we don't
  76. // want to rewrite the element prototype but should still
  77. // be enough to feature detect once at startup...
  78. let matchesMethod = parent.matches || parent.matchesSelector || parent.msMatchesSelector;
  79. // If we find a match, we're all set
  80. if( matchesMethod && matchesMethod.call( parent, selector ) ) {
  81. return parent;
  82. }
  83. // Keep searching
  84. parent = parent.parentNode;
  85. }
  86. return null;
  87. }
  88. /**
  89. * Handling the fullscreen functionality via the fullscreen API
  90. *
  91. * @see http://fullscreen.spec.whatwg.org/
  92. * @see https://developer.mozilla.org/en-US/docs/DOM/Using_fullscreen_mode
  93. */
  94. export const enterFullscreen = () => {
  95. let element = document.documentElement;
  96. // Check which implementation is available
  97. let requestMethod = element.requestFullscreen ||
  98. element.webkitRequestFullscreen ||
  99. element.webkitRequestFullScreen ||
  100. element.mozRequestFullScreen ||
  101. element.msRequestFullscreen;
  102. if( requestMethod ) {
  103. requestMethod.apply( element );
  104. }
  105. }
  106. /**
  107. * Injects the given CSS styles into the DOM.
  108. *
  109. * @param {string} value
  110. */
  111. export const injectStyleSheet = ( value ) => {
  112. let tag = document.createElement( 'style' );
  113. tag.type = 'text/css';
  114. if( tag.styleSheet ) {
  115. tag.styleSheet.cssText = value;
  116. }
  117. else {
  118. tag.appendChild( document.createTextNode( value ) );
  119. }
  120. document.getElementsByTagName( 'head' )[0].appendChild( tag );
  121. }