| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- /**
- * Window.js
- *
- * Copyright, Moxiecode Systems AB
- * Released under LGPL License.
- *
- * License: http://www.tinymce.com/license
- * Contributing: http://www.tinymce.com/contributing
- */
- /**
- * Creates a new window.
- *
- * @-x-less Window.less
- * @class tinymce.ui.Window
- * @extends tinymce.ui.FloatPanel
- */
- define("tinymce/ui/Window", [
- "tinymce/ui/FloatPanel",
- "tinymce/ui/Panel",
- "tinymce/ui/DomUtils",
- "tinymce/ui/DragHelper"
- ], function(FloatPanel, Panel, DomUtils, DragHelper) {
- "use strict";
- var Window = FloatPanel.extend({
- modal: true,
- Defaults: {
- border: 1,
- layout: 'flex',
- containerCls: 'panel',
- role: 'dialog',
- callbacks: {
- submit: function() {
- this.fire('submit', {data: this.toJSON()});
- },
- close: function() {
- this.close();
- }
- }
- },
- /**
- * Constructs a instance with the specified settings.
- *
- * @constructor
- * @param {Object} settings Name/value object with settings.
- */
- init: function(settings) {
- var self = this;
- self._super(settings);
- if (self.isRtl()) {
- self.addClass('rtl');
- }
- self.addClass('window');
- self._fixed = true;
- // Create statusbar
- if (settings.buttons) {
- self.statusbar = new Panel({
- layout: 'flex',
- border: '1 0 0 0',
- spacing: 3,
- padding: 10,
- align: 'center',
- pack: self.isRtl() ? 'start' : 'end',
- defaults: {
- type: 'button'
- },
- items: settings.buttons
- });
- self.statusbar.addClass('foot');
- self.statusbar.parent(self);
- }
- self.on('click', function(e) {
- if (e.target.className.indexOf(self.classPrefix + 'close') != -1) {
- self.close();
- }
- });
- self.on('cancel', function() {
- self.close();
- });
- self.aria('describedby', self.describedBy || self._id + '-none');
- self.aria('label', settings.title);
- self._fullscreen = false;
- },
- /**
- * Recalculates the positions of the controls in the current container.
- * This is invoked by the reflow method and shouldn't be called directly.
- *
- * @method recalc
- */
- recalc: function() {
- var self = this, statusbar = self.statusbar, layoutRect, width, x, needsRecalc;
- if (self._fullscreen) {
- self.layoutRect(DomUtils.getWindowSize());
- self.layoutRect().contentH = self.layoutRect().innerH;
- }
- self._super();
- layoutRect = self.layoutRect();
- // Resize window based on title width
- if (self.settings.title && !self._fullscreen) {
- width = layoutRect.headerW;
- if (width > layoutRect.w) {
- x = layoutRect.x - Math.max(0, width / 2);
- self.layoutRect({w: width, x: x});
- needsRecalc = true;
- }
- }
- // Resize window based on statusbar width
- if (statusbar) {
- statusbar.layoutRect({w: self.layoutRect().innerW}).recalc();
- width = statusbar.layoutRect().minW + layoutRect.deltaW;
- if (width > layoutRect.w) {
- x = layoutRect.x - Math.max(0, width - layoutRect.w);
- self.layoutRect({w: width, x: x});
- needsRecalc = true;
- }
- }
- // Recalc body and disable auto resize
- if (needsRecalc) {
- self.recalc();
- }
- },
- /**
- * Initializes the current controls layout rect.
- * This will be executed by the layout managers to determine the
- * default minWidth/minHeight etc.
- *
- * @method initLayoutRect
- * @return {Object} Layout rect instance.
- */
- initLayoutRect: function() {
- var self = this, layoutRect = self._super(), deltaH = 0, headEl;
- // Reserve vertical space for title
- if (self.settings.title && !self._fullscreen) {
- headEl = self.getEl('head');
- var size = DomUtils.getSize(headEl);
- layoutRect.headerW = size.width;
- layoutRect.headerH = size.height;
- deltaH += layoutRect.headerH;
- }
- // Reserve vertical space for statusbar
- if (self.statusbar) {
- deltaH += self.statusbar.layoutRect().h;
- }
- layoutRect.deltaH += deltaH;
- layoutRect.minH += deltaH;
- //layoutRect.innerH -= deltaH;
- layoutRect.h += deltaH;
- var rect = DomUtils.getWindowSize();
- layoutRect.x = Math.max(0, rect.w / 2 - layoutRect.w / 2);
- layoutRect.y = Math.max(0, rect.h / 2 - layoutRect.h / 2);
- return layoutRect;
- },
- /**
- * Renders the control as a HTML string.
- *
- * @method renderHtml
- * @return {String} HTML representing the control.
- */
- renderHtml: function() {
- var self = this, layout = self._layout, id = self._id, prefix = self.classPrefix;
- var settings = self.settings, headerHtml = '', footerHtml = '', html = settings.html;
- self.preRender();
- layout.preRender(self);
- if (settings.title) {
- headerHtml = (
- '<div id="' + id + '-head" class="' + prefix + 'window-head">' +
- '<div id="' + id + '-title" class="' + prefix + 'title">' + self.encode(settings.title) + '</div>' +
- '<button type="button" class="' + prefix + 'close" aria-hidden="true">\u00d7</button>' +
- '<div id="' + id + '-dragh" class="' + prefix + 'dragh"></div>' +
- '</div>'
- );
- }
- if (settings.url) {
- html = '<iframe src="' + settings.url + '" tabindex="-1"></iframe>';
- }
- if (typeof(html) == "undefined") {
- html = layout.renderHtml(self);
- }
- if (self.statusbar) {
- footerHtml = self.statusbar.renderHtml();
- }
- return (
- '<div id="' + id + '" class="' + self.classes() + '" hidefocus="1">' +
- '<div class="' + self.classPrefix + 'reset" role="application">' +
- headerHtml +
- '<div id="' + id + '-body" class="' + self.classes('body') + '">' +
- html +
- '</div>' +
- footerHtml +
- '</div>' +
- '</div>'
- );
- },
- /**
- * Switches the window fullscreen mode.
- *
- * @method fullscreen
- * @param {Boolean} state True/false state.
- * @return {tinymce.ui.Window} Current window instance.
- */
- fullscreen: function(state) {
- var self = this, documentElement = document.documentElement, slowRendering, prefix = self.classPrefix, layoutRect;
- if (state != self._fullscreen) {
- DomUtils.on(window, 'resize', function() {
- var time;
- if (self._fullscreen) {
- // Time the layout time if it's to slow use a timeout to not hog the CPU
- if (!slowRendering) {
- time = new Date().getTime();
- var rect = DomUtils.getWindowSize();
- self.moveTo(0, 0).resizeTo(rect.w, rect.h);
- if ((new Date().getTime()) - time > 50) {
- slowRendering = true;
- }
- } else {
- if (!self._timer) {
- self._timer = setTimeout(function() {
- var rect = DomUtils.getWindowSize();
- self.moveTo(0, 0).resizeTo(rect.w, rect.h);
- self._timer = 0;
- }, 50);
- }
- }
- }
- });
- layoutRect = self.layoutRect();
- self._fullscreen = state;
- if (!state) {
- self._borderBox = self.parseBox(self.settings.border);
- self.getEl('head').style.display = '';
- layoutRect.deltaH += layoutRect.headerH;
- DomUtils.removeClass(documentElement, prefix + 'fullscreen');
- DomUtils.removeClass(document.body, prefix + 'fullscreen');
- self.removeClass('fullscreen');
- self.moveTo(self._initial.x, self._initial.y).resizeTo(self._initial.w, self._initial.h);
- } else {
- self._initial = {x: layoutRect.x, y: layoutRect.y, w: layoutRect.w, h: layoutRect.h};
- self._borderBox = self.parseBox('0');
- self.getEl('head').style.display = 'none';
- layoutRect.deltaH -= layoutRect.headerH + 2;
- DomUtils.addClass(documentElement, prefix + 'fullscreen');
- DomUtils.addClass(document.body, prefix + 'fullscreen');
- self.addClass('fullscreen');
- var rect = DomUtils.getWindowSize();
- self.moveTo(0, 0).resizeTo(rect.w, rect.h);
- }
- }
- return self.reflow();
- },
- /**
- * Called after the control has been rendered.
- *
- * @method postRender
- */
- postRender: function() {
- var self = this, startPos;
- setTimeout(function() {
- self.addClass('in');
- }, 0);
- self._super();
- if (self.statusbar) {
- self.statusbar.postRender();
- }
- self.focus();
- this.dragHelper = new DragHelper(self._id + '-dragh', {
- start: function() {
- startPos = {
- x: self.layoutRect().x,
- y: self.layoutRect().y
- };
- },
- drag: function(e) {
- self.moveTo(startPos.x + e.deltaX, startPos.y + e.deltaY);
- }
- });
- self.on('submit', function(e) {
- if (!e.isDefaultPrevented()) {
- self.close();
- }
- });
- },
- /**
- * Fires a submit event with the serialized form.
- *
- * @method submit
- * @return {Object} Event arguments object.
- */
- submit: function() {
- return this.fire('submit', {data: this.toJSON()});
- },
- /**
- * Removes the current control from DOM and from UI collections.
- *
- * @method remove
- * @return {tinymce.ui.Control} Current control instance.
- */
- remove: function() {
- var self = this, prefix = self.classPrefix;
- self.dragHelper.destroy();
- self._super();
- if (self.statusbar) {
- this.statusbar.remove();
- }
- if (self._fullscreen) {
- DomUtils.removeClass(document.documentElement, prefix + 'fullscreen');
- DomUtils.removeClass(document.body, prefix + 'fullscreen');
- }
- },
- /**
- * Returns the contentWindow object of the iframe if it exists.
- *
- * @method getContentWindow
- * @return {Window} window object or null.
- */
- getContentWindow: function() {
- var ifr = this.getEl().getElementsByTagName('iframe')[0];
- return ifr ? ifr.contentWindow : null;
- }
- });
- return Window;
- });
|