]> git.wh0rd.org - tt-rss.git/blame - lib/dijit/_editor/plugins/FullScreen.js.uncompressed.js
modify dojo rebuild script to remove uncompressed files
[tt-rss.git] / lib / dijit / _editor / plugins / FullScreen.js.uncompressed.js
CommitLineData
f0cfe83e
AD
1define("dijit/_editor/plugins/FullScreen", [
2 "dojo/aspect",
3 "dojo/_base/declare", // declare
4 "dojo/dom-class", // domClass.add domClass.remove
5 "dojo/dom-geometry",
6 "dojo/dom-style",
7 "dojo/_base/event", // event.stop
8 "dojo/i18n", // i18n.getLocalization
9 "dojo/keys", // keys.F11 keys.TAB
10 "dojo/_base/lang", // lang.hitch
11 "dojo/on", // on()
12 "dojo/sniff", // has("ie"), has("quirks")
13 "dojo/_base/window", // win.body
14 "dojo/window", // winUtils.getBox winUtils.scrollIntoView
15 "../../focus", // focus.focus(), focus.curNode
16 "../_Plugin",
17 "../../form/ToggleButton",
18 "../../registry", // registry.getEnclosingWidget()
19 "dojo/i18n!../nls/commands"
20], function(aspect, declare, domClass, domGeometry, domStyle, event, i18n, keys, lang, on, has, win, winUtils,
21 focus, _Plugin, ToggleButton, registry){
22
23
24// module:
25// dijit/_editor/plugins/FullScreen
26
27
28var FullScreen = declare("dijit._editor.plugins.FullScreen",_Plugin,{
29 // summary:
30 // This plugin provides FullScreen capability to the editor. When
31 // toggled on, it will render the editor into the full window and
32 // overlay everything. It also binds to the hotkey: CTRL-SHIFT-F11
33 // for toggling fullscreen mode.
34
35 // zIndex: [public] Number
36 // zIndex value used for overlaying the full page.
37 // default is 500.
38 zIndex: 500,
39
40 // _origState: [private] Object
41 // The original view state of the editor.
42 _origState: null,
43
44 // _origiFrameState: [private] Object
45 // The original view state of the iframe of the editor.
46 _origiFrameState: null,
47
48 // _resizeHandle: [private] Object
49 // Connection point used for handling resize when window resizes.
50 _resizeHandle: null,
51
52 // isFullscreen: [const] boolean
53 // Read-Only variable used to denote of the editor is in fullscreen mode or not.
54 isFullscreen: false,
55
56 toggle: function(){
57 // summary:
58 // Function to allow programmatic toggling of the view.
59 this.button.set("checked", !this.button.get("checked"));
60 },
61
62 _initButton: function(){
63 // summary:
64 // Over-ride for creation of the resize button.
65 var strings = i18n.getLocalization("dijit._editor", "commands"),
66 editor = this.editor;
67 this.button = new ToggleButton({
68 label: strings["fullScreen"],
69 ownerDocument: editor.ownerDocument,
70 dir: editor.dir,
71 lang: editor.lang,
72 showLabel: false,
73 iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "FullScreen",
74 tabIndex: "-1",
75 onChange: lang.hitch(this, "_setFullScreen")
76 });
77 },
78
79 setEditor: function(editor){
80 // summary:
81 // Over-ride for the setting of the editor.
82 // editor: Object
83 // The editor to configure for this plugin to use.
84 this.editor = editor;
85 this._initButton();
86
87 this.editor.addKeyHandler(keys.F11, true, true, lang.hitch(this, function(e){
88 // Enable the CTRL-SHIFT-F11 hotkey for fullscreen mode.
89 this.toggle();
90 event.stop(e);
91 setTimeout(lang.hitch(this, function(){this.editor.focus();}), 250);
92 return true;
93 }));
94 this.connect(this.editor.domNode, "onkeydown", "_containFocus");
95 },
96
97 _containFocus: function(e){
98 // summary:
99 // When in Full Screen mode, it's good to try and retain focus in the editor
100 // so this function is intended to try and constrain the TAB key.
101 // e: Event
102 // The key event.
103 // tags:
104 // private
105 if(this.isFullscreen){
106 var ed = this.editor;
107 if(!ed.isTabIndent &&
108 ed._fullscreen_oldOnKeyDown &&
109 e.keyCode === keys.TAB){
110 // If we're in fullscreen mode, we want to take over how tab moves focus a bit.
111 // to keep it within the editor since it's hiding the rest of the page.
112 // IE hates changing focus IN the event handler, so need to put calls
113 // in a timeout. Gotta love IE.
114 // Also need to check for alternate view nodes if present and active.
115 var f = focus.curNode;
116 var avn = this._getAltViewNode();
117 if(f == ed.iframe ||
118 (avn && f === avn)){
119 setTimeout(lang.hitch(this, function(){
120 ed.toolbar.focus();
121 }), 10);
122 }else{
123 if(avn && domStyle.get(ed.iframe, "display") === "none"){
124 setTimeout(lang.hitch(this, function(){
125 focus.focus(avn);
126 }), 10);
127 }else{
128 setTimeout(lang.hitch(this, function(){
129 ed.focus();
130 }), 10);
131 }
132 }
133 event.stop(e);
134 }else if(ed._fullscreen_oldOnKeyDown){
135 // Only call up when it's a different function. Traps corner case event issue
136 // on IE which caused stack overflow on handler cleanup.
137 ed._fullscreen_oldOnKeyDown(e);
138 }
139 }
140 },
141
142 _resizeEditor: function(){
143 // summary:
144 // Function to handle resizing the editor as the viewport
145 // resizes (window scaled)
146 // tags:
147 // private
148 var vp = winUtils.getBox(this.editor.ownerDocument);
149 domGeometry.setMarginBox(this.editor.domNode, {
150 w: vp.w,
151 h: vp.h
152 });
153
154 //Adjust the internal heights too, as they can be a bit off.
155 var hHeight = this.editor.getHeaderHeight();
156 var fHeight = this.editor.getFooterHeight();
157 var extents = domGeometry.getPadBorderExtents(this.editor.domNode);
158 var fcpExtents = domGeometry.getPadBorderExtents(this.editor.iframe.parentNode);
159 var fcmExtents = domGeometry.getMarginExtents(this.editor.iframe.parentNode);
160
161 var cHeight = vp.h - (hHeight + extents.h + fHeight);
162 domGeometry.setMarginBox(this.editor.iframe.parentNode, {
163 h: cHeight,
164 w: vp.w
165 });
166 domGeometry.setMarginBox(this.editor.iframe, {
167 h: cHeight - (fcpExtents.h + fcmExtents.h)
168 });
169 },
170
171 _getAltViewNode: function(){
172 // summary:
173 // This function is intended as a hook point for setting an
174 // alternate view node for when in full screen mode and the
175 // editable iframe is hidden.
176 // tags:
177 // protected.
178 },
179
180 _setFullScreen: function(full){
181 // summary:
182 // Function to handle toggling between full screen and
183 // regular view.
184 // tags:
185 // private
186
187 //Alias this for shorter code.
188 var ed = this.editor;
189 var body = ed.ownerDocumentBody;
190 var editorParent = ed.domNode.parentNode;
191
192 var vp = winUtils.getBox(ed.ownerDocument);
193
194 this.isFullscreen = full;
195
196 if(full){
197 //Parent classes can royally screw up this plugin, so we
198 //have to set everything to position static.
199 while(editorParent && editorParent !== body){
200 domClass.add(editorParent, "dijitForceStatic");
201 editorParent = editorParent.parentNode;
202 }
203
204 // Save off the resize function. We want to kill its behavior.
205 this._editorResizeHolder = this.editor.resize;
206 ed.resize = function(){} ;
207
208 // Try to constrain focus control.
209 ed._fullscreen_oldOnKeyDown = ed.onKeyDown;
210 ed.onKeyDown = lang.hitch(this, this._containFocus);
211
212 this._origState = {};
213 this._origiFrameState = {};
214
215 // Store the basic editor state we have to restore later.
216 // Not using domStyle.get here, had problems, didn't
217 // give me stuff like 100%, gave me pixel calculated values.
218 // Need the exact original values.
219 var domNode = ed.domNode,
220 rawStyle = domNode && domNode.style || {};
221 this._origState = {
222 width: rawStyle.width || "",
223 height: rawStyle.height || "",
224 top: domStyle.get(domNode, "top") || "",
225 left: domStyle.get(domNode, "left") || "",
226 position: domStyle.get(domNode, "position") || "static",
227 marginBox: domGeometry.getMarginBox(ed.domNode)
228 };
229
230 // Store the iframe state we have to restore later.
231 // Not using domStyle.get here, had problems, didn't
232 // give me stuff like 100%, gave me pixel calculated values.
233 // Need the exact original values.
234 var iframe = ed.iframe,
235 iframeStyle = iframe && iframe.style || {};
236
237 var bc = domStyle.get(ed.iframe, "backgroundColor");
238 this._origiFrameState = {
239 backgroundColor: bc || "transparent",
240 width: iframeStyle.width || "auto",
241 height: iframeStyle.height || "auto",
242 zIndex: iframeStyle.zIndex || ""
243 };
244
245 // Okay, size everything.
246 domStyle.set(ed.domNode, {
247 position: "absolute",
248 top: "0px",
249 left: "0px",
250 zIndex: this.zIndex,
251 width: vp.w + "px",
252 height: vp.h + "px"
253 });
254
255 domStyle.set(ed.iframe, {
256 height: "100%",
257 width: "100%",
258 zIndex: this.zIndex,
259 backgroundColor: bc !== "transparent" &&
260 bc !== "rgba(0, 0, 0, 0)"?bc:"white"
261 });
262
263 domStyle.set(ed.iframe.parentNode, {
264 height: "95%",
265 width: "100%"
266 });
267
268 // Store the overflow state we have to restore later.
269 // IE had issues, so have to check that it's defined. Ugh.
270 if(body.style && body.style.overflow){
271 this._oldOverflow = domStyle.get(body, "overflow");
272 }else{
273 this._oldOverflow = "";
274 }
275
276 if(has("ie") && !has("quirks")){
277 // IE will put scrollbars in anyway, html (parent of body)
278 // also controls them in standards mode, so we have to
279 // remove them, argh.
280 if(body.parentNode &&
281 body.parentNode.style &&
282 body.parentNode.style.overflow){
283 this._oldBodyParentOverflow = body.parentNode.style.overflow;
284 }else{
285 try{
286 this._oldBodyParentOverflow = domStyle.get(body.parentNode, "overflow");
287 }catch(e){
288 this._oldBodyParentOverflow = "scroll";
289 }
290 }
291 domStyle.set(body.parentNode, "overflow", "hidden");
292 }
293 domStyle.set(body, "overflow", "hidden");
294
295 var resizer = function(){
296 // function to handle resize events.
297 // Will check current VP and only resize if
298 // different.
299 var vp = winUtils.getBox(ed.ownerDocument);
300 if("_prevW" in this && "_prevH" in this){
301 // No actual size change, ignore.
302 if(vp.w === this._prevW && vp.h === this._prevH){
303 return;
304 }
305 }else{
306 this._prevW = vp.w;
307 this._prevH = vp.h;
308 }
309 if(this._resizer){
310 clearTimeout(this._resizer);
311 delete this._resizer;
312 }
313 // Timeout it to help avoid spamming resize on IE.
314 // Works for all browsers.
315 this._resizer = setTimeout(lang.hitch(this, function(){
316 delete this._resizer;
317 this._resizeEditor();
318 }), 10);
319 };
320 this._resizeHandle = on(window, "resize", lang.hitch(this, resizer));
321
322 // Also monitor for direct calls to resize and adapt editor.
323 this._resizeHandle2 = aspect.after(ed, "onResize", lang.hitch(this, function(){
324 if(this._resizer){
325 clearTimeout(this._resizer);
326 delete this._resizer;
327 }
328 this._resizer = setTimeout(lang.hitch(this, function(){
329 delete this._resizer;
330 this._resizeEditor();
331 }), 10);
332 }));
333
334 // Call it once to work around IE glitchiness. Safe for other browsers too.
335 this._resizeEditor();
336 var dn = this.editor.toolbar.domNode;
337 setTimeout(function(){winUtils.scrollIntoView(dn);}, 250);
338 }else{
339 if(this._resizeHandle){
340 // Cleanup resizing listeners
341 this._resizeHandle.remove();
342 this._resizeHandle = null;
343 }
344 if(this._resizeHandle2){
345 // Cleanup resizing listeners
346 this._resizeHandle2.remove();
347 this._resizeHandle2 = null;
348 }
349 if(this._rst){
350 clearTimeout(this._rst);
351 this._rst = null;
352 }
353
354 //Remove all position static class assigns.
355 while(editorParent && editorParent !== body){
356 domClass.remove(editorParent, "dijitForceStatic");
357 editorParent = editorParent.parentNode;
358 }
359
360 // Restore resize function
361 if(this._editorResizeHolder){
362 this.editor.resize = this._editorResizeHolder;
363 }
364
365 if(!this._origState && !this._origiFrameState){
366 // If we actually didn't toggle, then don't do anything.
367 return;
368 }
369 if(ed._fullscreen_oldOnKeyDown){
370 ed.onKeyDown = ed._fullscreen_oldOnKeyDown;
371 delete ed._fullscreen_oldOnKeyDown;
372 }
373
374 // Add a timeout to make sure we don't have a resize firing in the
375 // background at the time of minimize.
376 var self = this;
377 setTimeout(function(){
378 // Restore all the editor state.
379 var mb = self._origState.marginBox;
380 var oh = self._origState.height;
381 if(has("ie") && !has("quirks")){
382 body.parentNode.style.overflow = self._oldBodyParentOverflow;
383 delete self._oldBodyParentOverflow;
384 }
385 domStyle.set(body, "overflow", self._oldOverflow);
386 delete self._oldOverflow;
387
388 domStyle.set(ed.domNode, self._origState);
389 domStyle.set(ed.iframe.parentNode, {
390 height: "",
391 width: ""
392 });
393 domStyle.set(ed.iframe, self._origiFrameState);
394 delete self._origState;
395 delete self._origiFrameState;
396 // In case it is contained in a layout and the layout changed size,
397 // go ahead and call resize.
398 var pWidget = registry.getEnclosingWidget(ed.domNode.parentNode);
399 if(pWidget && pWidget.resize){
400 pWidget.resize();
401 }else{
402 if(!oh || oh.indexOf("%") < 0){
403 // Resize if the original size wasn't set
404 // or wasn't in percent. Timeout is to avoid
405 // an IE crash in unit testing.
406 setTimeout(lang.hitch(this, function(){ed.resize({h: mb.h});}), 0);
407 }
408 }
409 winUtils.scrollIntoView(self.editor.toolbar.domNode);
410 }, 100);
411 }
412 },
413
414 updateState: function(){
415 // summary:
416 // Over-ride for button state control for disabled to work.
417 this.button.set("disabled", this.get("disabled"));
418 },
419
420 destroy: function(){
421 // summary:
422 // Over-ride to ensure the resize handle gets cleaned up.
423 if(this._resizeHandle){
424 // Cleanup resizing listeners
425 this._resizeHandle.remove();
426 this._resizeHandle = null;
427 }
428 if(this._resizeHandle2){
429 // Cleanup resizing listeners
430 this._resizeHandle2.remove();
431 this._resizeHandle2 = null;
432 }
433 if(this._resizer){
434 clearTimeout(this._resizer);
435 this._resizer = null;
436 }
437 this.inherited(arguments);
438 }
439});
440
441// Register this plugin.
442// For back-compat accept "fullscreen" (all lowercase) too, remove in 2.0
443_Plugin.registry["fullScreen"] = _Plugin.registry["fullscreen"] = function(args){
444 return new FullScreen({
445 zIndex: ("zIndex" in args)?args.zIndex:500
446 });
447};
448
449return FullScreen;
450});