You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Etherpad.js 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /* global $ */
  2. import VideoLayout from "../videolayout/VideoLayout";
  3. import LargeContainer from '../videolayout/LargeContainer';
  4. import UIUtil from "../util/UIUtil";
  5. import UIEvents from "../../../service/UI/UIEvents";
  6. import SidePanelToggler from "../side_pannels/SidePanelToggler";
  7. import FilmStrip from '../videolayout/FilmStrip';
  8. /**
  9. * Etherpad options.
  10. */
  11. const options = $.param({
  12. showControns: true,
  13. showChat: false,
  14. showLineNumbers: true,
  15. useMonospaceFont: false
  16. });
  17. function bubbleIframeMouseMove(iframe){
  18. var existingOnMouseMove = iframe.contentWindow.onmousemove;
  19. iframe.contentWindow.onmousemove = function(e){
  20. if(existingOnMouseMove) existingOnMouseMove(e);
  21. var evt = document.createEvent("MouseEvents");
  22. var boundingClientRect = iframe.getBoundingClientRect();
  23. evt.initMouseEvent(
  24. "mousemove",
  25. true, // bubbles
  26. false, // not cancelable
  27. window,
  28. e.detail,
  29. e.screenX,
  30. e.screenY,
  31. e.clientX + boundingClientRect.left,
  32. e.clientY + boundingClientRect.top,
  33. e.ctrlKey,
  34. e.altKey,
  35. e.shiftKey,
  36. e.metaKey,
  37. e.button,
  38. null // no related element
  39. );
  40. iframe.dispatchEvent(evt);
  41. };
  42. }
  43. /**
  44. * Default Etherpad frame width.
  45. */
  46. const DEFAULT_WIDTH = 640;
  47. /**
  48. * Default Etherpad frame height.
  49. */
  50. const DEFAULT_HEIGHT = 480;
  51. const ETHERPAD_CONTAINER_TYPE = "etherpad";
  52. /**
  53. * Container for Etherpad iframe.
  54. */
  55. class Etherpad extends LargeContainer {
  56. constructor (domain, name) {
  57. super();
  58. const iframe = document.createElement('iframe');
  59. iframe.src = domain + name + '?' + options;
  60. iframe.frameBorder = 0;
  61. iframe.scrolling = "no";
  62. iframe.width = DEFAULT_WIDTH;
  63. iframe.height = DEFAULT_HEIGHT;
  64. iframe.setAttribute('style', 'visibility: hidden;');
  65. this.container.appendChild(iframe);
  66. iframe.onload = function() {
  67. document.domain = document.domain;
  68. bubbleIframeMouseMove(iframe);
  69. setTimeout(function() {
  70. const doc = iframe.contentDocument;
  71. // the iframes inside of the etherpad are
  72. // not yet loaded when the etherpad iframe is loaded
  73. const outer = doc.getElementsByName("ace_outer")[0];
  74. bubbleIframeMouseMove(outer);
  75. const inner = doc.getElementsByName("ace_inner")[0];
  76. bubbleIframeMouseMove(inner);
  77. }, 2000);
  78. };
  79. this.iframe = iframe;
  80. }
  81. get isOpen () {
  82. return !!this.iframe;
  83. }
  84. get container () {
  85. return document.getElementById('etherpad');
  86. }
  87. resize (containerWidth, containerHeight, animate) {
  88. let height = containerHeight - FilmStrip.getFilmStripHeight();
  89. let width = containerWidth;
  90. $(this.iframe).width(width).height(height);
  91. }
  92. show () {
  93. const $iframe = $(this.iframe);
  94. const $container = $(this.container);
  95. let self = this;
  96. return new Promise(resolve => {
  97. $iframe.fadeIn(300, function () {
  98. self.bodyBackground = document.body.style.background;
  99. document.body.style.background = '#eeeeee';
  100. $iframe.css({visibility: 'visible'});
  101. $container.css({zIndex: 2});
  102. resolve();
  103. });
  104. });
  105. }
  106. hide () {
  107. const $iframe = $(this.iframe);
  108. const $container = $(this.container);
  109. document.body.style.background = this.bodyBackground;
  110. return new Promise(resolve => {
  111. $iframe.fadeOut(300, function () {
  112. $iframe.css({visibility: 'hidden'});
  113. $container.css({zIndex: 0});
  114. resolve();
  115. });
  116. });
  117. }
  118. /**
  119. * @return {boolean} do not switch on dominant speaker event if on stage.
  120. */
  121. stayOnStage () {
  122. return true;
  123. }
  124. }
  125. /**
  126. * Manager of the Etherpad frame.
  127. */
  128. export default class EtherpadManager {
  129. constructor (domain, name, eventEmitter) {
  130. if (!domain || !name) {
  131. throw new Error("missing domain or name");
  132. }
  133. this.domain = domain;
  134. this.name = name;
  135. this.eventEmitter = eventEmitter;
  136. this.etherpad = null;
  137. }
  138. get isOpen () {
  139. return !!this.etherpad;
  140. }
  141. isVisible() {
  142. return VideoLayout.isLargeContainerTypeVisible(ETHERPAD_CONTAINER_TYPE);
  143. }
  144. /**
  145. * Create new Etherpad frame.
  146. */
  147. openEtherpad () {
  148. this.etherpad = new Etherpad(this.domain, this.name);
  149. VideoLayout.addLargeVideoContainer(
  150. ETHERPAD_CONTAINER_TYPE,
  151. this.etherpad
  152. );
  153. }
  154. /**
  155. * Toggle Etherpad frame visibility.
  156. * Open new Etherpad frame if there is no Etherpad frame yet.
  157. */
  158. toggleEtherpad () {
  159. if (!this.isOpen) {
  160. this.openEtherpad();
  161. }
  162. let isVisible = this.isVisible();
  163. VideoLayout.showLargeVideoContainer(
  164. ETHERPAD_CONTAINER_TYPE, !isVisible);
  165. this.eventEmitter
  166. .emit(UIEvents.TOGGLED_SHARED_DOCUMENT, !isVisible);
  167. }
  168. }