dialog.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. ///import core
  2. ///import uicore
  3. ///import ui/mask.js
  4. ///import ui/button.js
  5. (function (){
  6. var utils = baidu.editor.utils,
  7. domUtils = baidu.editor.dom.domUtils,
  8. uiUtils = baidu.editor.ui.uiUtils,
  9. Mask = baidu.editor.ui.Mask,
  10. UIBase = baidu.editor.ui.UIBase,
  11. Button = baidu.editor.ui.Button,
  12. Dialog = baidu.editor.ui.Dialog = function (options){
  13. if(options.name){
  14. var name = options.name;
  15. var cssRules = options.cssRules;
  16. if(!options.className){
  17. options.className = 'edui-for-' + name;
  18. }
  19. if(cssRules){
  20. options.cssRules = '.edui-default .edui-for-'+ name +' .edui-dialog-content {'+ cssRules +'}'
  21. }
  22. }
  23. this.initOptions(utils.extend({
  24. autoReset: true,
  25. draggable: true,
  26. onok: function (){},
  27. oncancel: function (){},
  28. onclose: function (t, ok){
  29. return ok ? this.onok() : this.oncancel();
  30. },
  31. //是否控制dialog中的scroll事件, 默认为不阻止
  32. holdScroll: false
  33. },options));
  34. this.initDialog();
  35. };
  36. var modalMask;
  37. var dragMask;
  38. var activeDialog;
  39. Dialog.prototype = {
  40. draggable: false,
  41. uiName: 'dialog',
  42. initDialog: function (){
  43. var me = this,
  44. theme=this.editor.options.theme;
  45. if(this.cssRules){
  46. utils.cssRule('edui-customize-'+this.name+'-style',this.cssRules);
  47. }
  48. this.initUIBase();
  49. this.modalMask = (modalMask || (modalMask = new Mask({
  50. className: 'edui-dialog-modalmask',
  51. theme:theme,
  52. onclick: function (){
  53. activeDialog && activeDialog.close(false);
  54. }
  55. })));
  56. this.dragMask = (dragMask || (dragMask = new Mask({
  57. className: 'edui-dialog-dragmask',
  58. theme:theme
  59. })));
  60. this.closeButton = new Button({
  61. className: 'edui-dialog-closebutton',
  62. title: me.closeDialog,
  63. theme:theme,
  64. onclick: function (){
  65. me.close(false);
  66. }
  67. });
  68. this.fullscreen && this.initResizeEvent();
  69. if (this.buttons) {
  70. for (var i=0; i<this.buttons.length; i++) {
  71. if (!(this.buttons[i] instanceof Button)) {
  72. this.buttons[i] = new Button(utils.extend(this.buttons[i],{
  73. editor : this.editor
  74. },true));
  75. }
  76. }
  77. }
  78. },
  79. initResizeEvent: function () {
  80. var me = this;
  81. domUtils.on( window, "resize", function () {
  82. if ( me._hidden || me._hidden === undefined ) {
  83. return;
  84. }
  85. if ( me.__resizeTimer ) {
  86. window.clearTimeout( me.__resizeTimer );
  87. }
  88. me.__resizeTimer = window.setTimeout( function () {
  89. me.__resizeTimer = null;
  90. var dialogWrapNode = me.getDom(),
  91. contentNode = me.getDom('content'),
  92. wrapRect = UE.ui.uiUtils.getClientRect( dialogWrapNode ),
  93. contentRect = UE.ui.uiUtils.getClientRect( contentNode ),
  94. vpRect = uiUtils.getViewportRect();
  95. contentNode.style.width = ( vpRect.width - wrapRect.width + contentRect.width ) + "px";
  96. contentNode.style.height = ( vpRect.height - wrapRect.height + contentRect.height ) + "px";
  97. dialogWrapNode.style.width = vpRect.width + "px";
  98. dialogWrapNode.style.height = vpRect.height + "px";
  99. me.fireEvent( "resize" );
  100. }, 100 );
  101. } );
  102. },
  103. fitSize: function (){
  104. var popBodyEl = this.getDom('body');
  105. // if (!(baidu.editor.browser.ie && baidu.editor.browser.version == 7)) {
  106. // uiUtils.removeStyle(popBodyEl, 'width');
  107. // uiUtils.removeStyle(popBodyEl, 'height');
  108. // }
  109. var size = this.mesureSize();
  110. popBodyEl.style.width = size.width + 'px';
  111. popBodyEl.style.height = size.height + 'px';
  112. return size;
  113. },
  114. safeSetOffset: function (offset){
  115. var me = this;
  116. var el = me.getDom();
  117. var vpRect = uiUtils.getViewportRect();
  118. var rect = uiUtils.getClientRect(el);
  119. var left = offset.left;
  120. if (left + rect.width > vpRect.right) {
  121. left = vpRect.right - rect.width;
  122. }
  123. var top = offset.top;
  124. if (top + rect.height > vpRect.bottom) {
  125. top = vpRect.bottom - rect.height;
  126. }
  127. el.style.left = Math.max(left, 0) + 'px';
  128. el.style.top = Math.max(top, 0) + 'px';
  129. },
  130. showAtCenter: function (){
  131. var vpRect = uiUtils.getViewportRect();
  132. if ( !this.fullscreen ) {
  133. this.getDom().style.display = '';
  134. var popSize = this.fitSize();
  135. var titleHeight = this.getDom('titlebar').offsetHeight | 0;
  136. var left = vpRect.width / 2 - popSize.width / 2;
  137. var top = vpRect.height / 2 - (popSize.height - titleHeight) / 2 - titleHeight;
  138. var popEl = this.getDom();
  139. this.safeSetOffset({
  140. left: Math.max(left | 0, 0),
  141. top: Math.max(top | 0, 0)
  142. });
  143. if (!domUtils.hasClass(popEl, 'edui-state-centered')) {
  144. popEl.className += ' edui-state-centered';
  145. }
  146. } else {
  147. var dialogWrapNode = this.getDom(),
  148. contentNode = this.getDom('content');
  149. dialogWrapNode.style.display = "block";
  150. var wrapRect = UE.ui.uiUtils.getClientRect( dialogWrapNode ),
  151. contentRect = UE.ui.uiUtils.getClientRect( contentNode );
  152. dialogWrapNode.style.left = "-100000px";
  153. contentNode.style.width = ( vpRect.width - wrapRect.width + contentRect.width ) + "px";
  154. contentNode.style.height = ( vpRect.height - wrapRect.height + contentRect.height ) + "px";
  155. dialogWrapNode.style.width = vpRect.width + "px";
  156. dialogWrapNode.style.height = vpRect.height + "px";
  157. dialogWrapNode.style.left = 0;
  158. //保存环境的overflow值
  159. this._originalContext = {
  160. html: {
  161. overflowX: document.documentElement.style.overflowX,
  162. overflowY: document.documentElement.style.overflowY
  163. },
  164. body: {
  165. overflowX: document.body.style.overflowX,
  166. overflowY: document.body.style.overflowY
  167. }
  168. };
  169. document.documentElement.style.overflowX = 'hidden';
  170. document.documentElement.style.overflowY = 'hidden';
  171. document.body.style.overflowX = 'hidden';
  172. document.body.style.overflowY = 'hidden';
  173. }
  174. this._show();
  175. },
  176. getContentHtml: function (){
  177. var contentHtml = '';
  178. if (typeof this.content == 'string') {
  179. contentHtml = this.content;
  180. } else if (this.iframeUrl) {
  181. contentHtml = '<span id="'+ this.id +'_contmask" class="dialogcontmask"></span><iframe id="'+ this.id +
  182. '_iframe" class="%%-iframe" height="100%" width="100%" frameborder="0" src="'+ this.iframeUrl +'"></iframe>';
  183. }
  184. return contentHtml;
  185. },
  186. getHtmlTpl: function (){
  187. var footHtml = '';
  188. if (this.buttons) {
  189. var buff = [];
  190. for (var i=0; i<this.buttons.length; i++) {
  191. buff[i] = this.buttons[i].renderHtml();
  192. }
  193. footHtml = '<div class="%%-foot">' +
  194. '<div id="##_buttons" class="%%-buttons">' + buff.join('') + '</div>' +
  195. '</div>';
  196. }
  197. return '<div id="##" class="%%"><div '+ ( !this.fullscreen ? 'class="%%"' : 'class="%%-wrap edui-dialog-fullscreen-flag"' ) +'><div id="##_body" class="%%-body">' +
  198. '<div class="%%-shadow"></div>' +
  199. '<div id="##_titlebar" class="%%-titlebar">' +
  200. '<div class="%%-draghandle" onmousedown="$$._onTitlebarMouseDown(event, this);">' +
  201. '<span class="%%-caption">' + (this.title || '') + '</span>' +
  202. '</div>' +
  203. this.closeButton.renderHtml() +
  204. '</div>' +
  205. '<div id="##_content" class="%%-content">'+ ( this.autoReset ? '' : this.getContentHtml()) +'</div>' +
  206. footHtml +
  207. '</div></div></div>';
  208. },
  209. postRender: function (){
  210. // todo: 保持居中/记住上次关闭位置选项
  211. if (!this.modalMask.getDom()) {
  212. this.modalMask.render();
  213. this.modalMask.hide();
  214. }
  215. if (!this.dragMask.getDom()) {
  216. this.dragMask.render();
  217. this.dragMask.hide();
  218. }
  219. var me = this;
  220. this.addListener('show', function (){
  221. me.modalMask.show(this.getDom().style.zIndex - 2);
  222. });
  223. this.addListener('hide', function (){
  224. me.modalMask.hide();
  225. });
  226. if (this.buttons) {
  227. for (var i=0; i<this.buttons.length; i++) {
  228. this.buttons[i].postRender();
  229. }
  230. }
  231. domUtils.on(window, 'resize', function (){
  232. setTimeout(function (){
  233. if (!me.isHidden()) {
  234. me.safeSetOffset(uiUtils.getClientRect(me.getDom()));
  235. }
  236. });
  237. });
  238. //hold住scroll事件,防止dialog的滚动影响页面
  239. // if( this.holdScroll ) {
  240. //
  241. // if( !me.iframeUrl ) {
  242. // domUtils.on( document.getElementById( me.id + "_iframe"), !browser.gecko ? "mousewheel" : "DOMMouseScroll", function(e){
  243. // domUtils.preventDefault(e);
  244. // } );
  245. // } else {
  246. // me.addListener('dialogafterreset', function(){
  247. // window.setTimeout(function(){
  248. // var iframeWindow = document.getElementById( me.id + "_iframe").contentWindow;
  249. //
  250. // if( browser.ie ) {
  251. //
  252. // var timer = window.setInterval(function(){
  253. //
  254. // if( iframeWindow.document && iframeWindow.document.body ) {
  255. // window.clearInterval( timer );
  256. // timer = null;
  257. // domUtils.on( iframeWindow.document.body, !browser.gecko ? "mousewheel" : "DOMMouseScroll", function(e){
  258. // domUtils.preventDefault(e);
  259. // } );
  260. // }
  261. //
  262. // }, 100);
  263. //
  264. // } else {
  265. // domUtils.on( iframeWindow, !browser.gecko ? "mousewheel" : "DOMMouseScroll", function(e){
  266. // domUtils.preventDefault(e);
  267. // } );
  268. // }
  269. //
  270. // }, 1);
  271. // });
  272. // }
  273. //
  274. // }
  275. this._hide();
  276. },
  277. mesureSize: function (){
  278. var body = this.getDom('body');
  279. var width = uiUtils.getClientRect(this.getDom('content')).width;
  280. var dialogBodyStyle = body.style;
  281. dialogBodyStyle.width = width;
  282. return uiUtils.getClientRect(body);
  283. },
  284. _onTitlebarMouseDown: function (evt, el){
  285. if (this.draggable) {
  286. var rect;
  287. var vpRect = uiUtils.getViewportRect();
  288. var me = this;
  289. uiUtils.startDrag(evt, {
  290. ondragstart: function (){
  291. rect = uiUtils.getClientRect(me.getDom());
  292. me.getDom('contmask').style.visibility = 'visible';
  293. me.dragMask.show(me.getDom().style.zIndex - 1);
  294. },
  295. ondragmove: function (x, y){
  296. var left = rect.left + x;
  297. var top = rect.top + y;
  298. me.safeSetOffset({
  299. left: left,
  300. top: top
  301. });
  302. },
  303. ondragstop: function (){
  304. me.getDom('contmask').style.visibility = 'hidden';
  305. domUtils.removeClasses(me.getDom(), ['edui-state-centered']);
  306. me.dragMask.hide();
  307. }
  308. });
  309. }
  310. },
  311. reset: function (){
  312. this.getDom('content').innerHTML = this.getContentHtml();
  313. this.fireEvent('dialogafterreset');
  314. },
  315. _show: function (){
  316. if (this._hidden) {
  317. this.getDom().style.display = '';
  318. //要高过编辑器的zindxe
  319. this.editor.container.style.zIndex && (this.getDom().style.zIndex = this.editor.container.style.zIndex * 1 + 10);
  320. this._hidden = false;
  321. this.fireEvent('show');
  322. baidu.editor.ui.uiUtils.getFixedLayer().style.zIndex = this.getDom().style.zIndex - 4;
  323. }
  324. },
  325. isHidden: function (){
  326. return this._hidden;
  327. },
  328. _hide: function (){
  329. if (!this._hidden) {
  330. var wrapNode = this.getDom();
  331. wrapNode.style.display = 'none';
  332. wrapNode.style.zIndex = '';
  333. wrapNode.style.width = '';
  334. wrapNode.style.height = '';
  335. this._hidden = true;
  336. this.fireEvent('hide');
  337. }
  338. },
  339. open: function (){
  340. if (this.autoReset) {
  341. //有可能还没有渲染
  342. try{
  343. this.reset();
  344. }catch(e){
  345. this.render();
  346. this.open()
  347. }
  348. }
  349. this.showAtCenter();
  350. if (this.iframeUrl) {
  351. try {
  352. this.getDom('iframe').focus();
  353. } catch(ex){}
  354. }
  355. activeDialog = this;
  356. },
  357. _onCloseButtonClick: function (evt, el){
  358. this.close(false);
  359. },
  360. close: function (ok){
  361. if (this.fireEvent('close', ok) !== false) {
  362. //还原环境
  363. if ( this.fullscreen ) {
  364. document.documentElement.style.overflowX = this._originalContext.html.overflowX;
  365. document.documentElement.style.overflowY = this._originalContext.html.overflowY;
  366. document.body.style.overflowX = this._originalContext.body.overflowX;
  367. document.body.style.overflowY = this._originalContext.body.overflowY;
  368. delete this._originalContext;
  369. }
  370. this._hide();
  371. //销毁content
  372. var content = this.getDom('content');
  373. var iframe = this.getDom('iframe');
  374. if (content && iframe) {
  375. var doc = iframe.contentDocument || iframe.contentWindow.document;
  376. doc && (doc.body.innerHTML = '');
  377. domUtils.remove(content);
  378. }
  379. }
  380. }
  381. };
  382. utils.inherits(Dialog, UIBase);
  383. })();