1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
4
* Copyright (C) 2003-2010 Frederico Caldeira Knabben
8
* Licensed under the terms of any of the following licenses at your
11
* - GNU General Public License Version 2 or later (the "GPL")
12
* http://www.gnu.org/licenses/gpl.html
14
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
15
* http://www.gnu.org/licenses/lgpl.html
17
* - Mozilla Public License Version 1.1 or later (the "MPL")
18
* http://www.mozilla.org/MPL/MPL-1.1.html
22
* This page is used by all dialog box as the container.
24
<html xmlns="http://www.w3.org/1999/xhtml">
27
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
28
<meta name="robots" content="noindex, nofollow" />
29
<script type="text/javascript">
32
// Domain relaxation logic.
35
var d = document.domain ;
39
// Test if we can access a parent property.
42
var parentDomain = ( Args().TopWindow || E ).document.domain ;
44
if ( document.domain != parentDomain )
45
document.domain = parentDomain ;
51
// Remove a domain part: www.mytest.example.com => mytest.example.com => example.com ...
52
d = d.replace( /.*?(?:\.|$)/, '' ) ;
55
break ; // It was not able to detect the domain.
61
var E = frameElement._DialogArguments.Editor ;
63
// It seems referencing to frameElement._DialogArguments directly would lead to memory leaks in IE.
64
// So let's use functions to access its members instead.
67
return frameElement._DialogArguments ;
70
function ParentDialog( dialog )
72
return dialog ? dialog._ParentDialog : frameElement._ParentDialog ;
76
var FCKTools = E.FCKTools ;
77
var FCKDomTools = E.FCKDomTools ;
78
var FCKDialog = E.FCKDialog ;
79
var FCKBrowserInfo = E.FCKBrowserInfo ;
80
var FCKConfig = E.FCKConfig ;
82
// Steal the focus so that the caret would no longer stay in the editor iframe.
86
document.write( FCKTools.GetStyleHtml( FCKConfig.SkinDialogCSS ) ) ;
88
// Sets the language direction.
89
var langDir = E.FCKLang.Dir ;
91
// For IE6-, the fck_dialog_ie6.js is loaded, used to fix limitations in the browser.
92
if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 )
93
document.write( '<' + 'script type="text/javascript" src="' + FCKConfig.SkinPath + 'fck_dialog_ie6.js"><' + '\/script>' ) ;
95
FCKTools.RegisterDollarFunction( window ) ;
97
// Resize related functions.
98
var Sizer = function()
100
var bAutoSize = false ;
103
// Sets whether the dialog should auto-resize according to its content's height.
104
SetAutoSize : function( autoSize )
106
bAutoSize = autoSize ;
110
// Fit the dialog container's layout to the inner iframe's external size.
111
RefreshContainerSize : function()
113
var frmMain = $( 'frmMain' ) ;
117
// Get the container size.
118
var height = $( 'contents' ).offsetHeight ;
120
// Subtract the size of other elements.
121
height -= $( 'TitleArea' ).offsetHeight ;
122
height -= $( 'TabsRow' ).offsetHeight ;
123
height -= $( 'PopupButtons' ).offsetHeight ;
125
frmMain.style.height = Math.max( height, 0 ) + 'px' ;
129
// Resize and re-layout the dialog.
130
// Triggers the onresize event for the layout logic.
131
ResizeDialog : function( width, height )
133
FCKDomTools.SetElementStyles( window.frameElement,
135
'width' : width + 'px',
136
'height' : height + 'px'
139
// If the skin have defined a function for resize fixes, call it now.
140
if ( typeof window.DoResizeFixes == 'function' )
141
window.DoResizeFixes() ;
144
// if bAutoSize is true, automatically fit the dialog size and layout to
145
// accomodate the inner iframe's internal height.
146
// if bAutoSize is false, then only the layout logic for the dialog decorations
147
// is run to accomodate the inner iframe's external height.
148
RefreshSize : function()
152
var frmMain = $( 'frmMain' ) ;
153
var innerDoc = frmMain.contentWindow.document ;
154
var isStrict = FCKTools.IsStrictMode( innerDoc ) ;
156
// Get the size of the frame contents.
157
var innerWidth = isStrict ? innerDoc.documentElement.scrollWidth : innerDoc.body.scrollWidth ;
158
var innerHeight = isStrict ? innerDoc.documentElement.scrollHeight : innerDoc.body.scrollHeight ;
160
// Get the current frame size.
161
var frameSize = FCKTools.GetViewPaneSize( frmMain.contentWindow ) ;
163
var deltaWidth = innerWidth - frameSize.Width ;
164
var deltaHeight = innerHeight - frameSize.Height ;
166
// If the contents fits the current size.
167
if ( deltaWidth <= 0 && deltaHeight <= 0 )
170
var dialogWidth = frameElement.offsetWidth + Math.max( deltaWidth, 0 ) ;
171
var dialogHeight = frameElement.offsetHeight + Math.max( deltaHeight, 0 ) ;
173
this.ResizeDialog( dialogWidth, dialogHeight ) ;
175
this.RefreshContainerSize() ;
180
* Safari seems to have a bug with the time when RefreshSize() is executed - it
181
* thinks frmMain's innerHeight is 0 if we query the value too soon after the
182
* page is loaded in some circumstances. (#1316)
183
* TODO : Maybe this is not needed anymore after #35.
185
if ( FCKBrowserInfo.IsSafari )
187
var originalRefreshSize = retval.RefreshSize ;
189
retval.RefreshSize = function()
191
FCKTools.SetTimeout( originalRefreshSize, 1, retval ) ;
196
* IE6 has a similar bug where it sometimes thinks $('contents') has an
197
* offsetHeight of 0 (#2114).
199
if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 )
201
var originalRefreshContainerSize = retval.RefreshContainerSize ;
202
retval.RefreshContainerSize = function()
204
FCKTools.SetTimeout( originalRefreshContainerSize, 1, retval ) ;
208
window.onresize = function()
210
retval.RefreshContainerSize() ;
213
window.SetAutoSize = FCKTools.Bind( retval, retval.SetAutoSize ) ;
218
// Manages the throbber image that appears if the inner part of dialog is taking too long to load.
219
var Throbber = function()
223
var updateThrobber = function()
225
var throbberParent = $( 'throbberBlock' ) ;
226
var throbberBlocks = throbberParent.childNodes ;
227
var lastClass = throbberParent.lastChild.className ;
229
// From the last to the second one, copy the class from the previous one.
230
for ( var i = throbberBlocks.length - 1 ; i > 0 ; i-- )
231
throbberBlocks[i].className = throbberBlocks[i-1].className ;
233
// For the first one, copy the last class (rotation).
234
throbberBlocks[0].className = lastClass ;
238
Show : function( waitMilliseconds )
240
// Auto-setup the Show function to be called again after the
241
// requested amount of time.
242
if ( waitMilliseconds && waitMilliseconds > 0 )
244
timer = FCKTools.SetTimeout( this.Show, waitMilliseconds, this, null, window ) ;
248
var throbberParent = $( 'throbberBlock' ) ;
250
if (throbberParent.childNodes.length == 0)
252
// Create the throbber blocks.
253
var classIds = [ 1,2,3,4,5,4,3,2 ] ;
254
while ( classIds.length > 0 )
255
throbberParent.appendChild( document.createElement( 'div' ) ).className = ' throbber_' + classIds.shift() ;
258
// Center the throbber.
259
var frm = $( 'contents' ) ;
260
var frmCoords = FCKTools.GetDocumentPosition( window, frm ) ;
261
var x = frmCoords.x + ( frm.offsetWidth - throbberParent.offsetWidth ) / 2 ;
262
var y = frmCoords.y + ( frm.offsetHeight - throbberParent.offsetHeight ) / 2 ;
263
throbberParent.style.left = parseInt( x, 10 ) + 'px' ;
264
throbberParent.style.top = parseInt( y, 10 ) + 'px' ;
267
throbberParent.style.visibility = '' ;
269
// Hide tabs and buttons:
270
$( 'Tabs' ).style.visibility = 'hidden' ;
271
$( 'PopupButtons' ).style.visibility = 'hidden' ;
273
// Setup the animation interval.
274
timer = setInterval( updateThrobber, 100 ) ;
281
clearInterval( timer ) ;
285
$( 'throbberBlock' ).style.visibility = 'hidden' ;
287
// Show tabs and buttons:
288
$( 'Tabs' ).style.visibility = '' ;
289
$( 'PopupButtons' ).style.visibility = '' ;
294
// Drag and drop handlers.
295
var DragAndDrop = function()
297
var registeredWindows = [] ;
301
var cleanUpHandlers = function()
303
for ( var i = 0 ; i < registeredWindows.length ; i++ )
305
FCKTools.RemoveEventListener( registeredWindows[i].document, 'mousemove', dragMouseMoveHandler ) ;
306
FCKTools.RemoveEventListener( registeredWindows[i].document, 'mouseup', dragMouseUpHandler ) ;
310
var dragMouseMoveHandler = function( evt )
316
evt = FCKTools.GetElementDocument( this ).parentWindow.event ;
318
// Updated the last coordinates.
327
x : currentPos.x + ( currentCoords.x - lastCoords.x ),
328
y : currentPos.y + ( currentCoords.y - lastCoords.y )
331
lastCoords = currentCoords ;
333
frameElement.style.left = currentPos.x + 'px' ;
334
frameElement.style.top = currentPos.y + 'px' ;
336
if ( evt.preventDefault )
337
evt.preventDefault() ;
339
evt.returnValue = false ;
342
var dragMouseUpHandler = function( evt )
347
evt = FCKTools.GetElementDocument( this ).parentWindow.event ;
354
MouseDownHandler : function( evt )
359
view = FCKTools.GetElementDocument( this ).parentWindow ;
365
var target = evt.srcElement || evt.target ;
366
if ( target.id == 'closeButton' || target.className == 'PopupTab' || target.className == 'PopupTabSelected' )
375
// Save the current IFRAME position.
378
x : parseInt( FCKDomTools.GetCurrentElementStyle( frameElement, 'left' ), 10 ),
379
y : parseInt( FCKDomTools.GetCurrentElementStyle( frameElement, 'top' ), 10 )
382
for ( var i = 0 ; i < registeredWindows.length ; i++ )
384
FCKTools.AddEventListener( registeredWindows[i].document, 'mousemove', dragMouseMoveHandler ) ;
385
FCKTools.AddEventListener( registeredWindows[i].document, 'mouseup', dragMouseUpHandler ) ;
388
if ( evt.preventDefault )
389
evt.preventDefault() ;
391
evt.returnValue = false ;
394
RegisterHandlers : function( w )
396
registeredWindows.push( w ) ;
401
// Selection related functions.
402
//(Became simple shortcuts after the fix for #1990)
406
* Ensures that the editing area contains an active selection. This is a
407
* requirement for IE, as it looses the selection when the focus moves to other
410
EnsureSelection : function()
412
// Move the focus to the Cancel button so even if the dialog contains a
413
// contentEditable element the selection is properly restored in the editor #2496
415
$( 'btnCancel' ).focus() ;
417
FCK.Selection.Restore() ;
421
* Get the FCKSelection object for the editor instance.
423
GetSelection : function()
425
return FCK.Selection ;
429
* Get the selected element in the editing area (for object selections).
431
GetSelectedElement : function()
433
return FCK.Selection.GetSelectedElement() ;
437
// Tab related functions.
438
var Tabs = function()
440
// Only element ids should be stored here instead of element references since setSelectedTab and TabDiv_OnClick
441
// would build circular references with the element references inside and cause memory leaks in IE6.
442
var oTabs = new Object() ;
444
var setSelectedTab = function( tabCode )
446
for ( var sCode in oTabs )
448
if ( sCode == tabCode )
449
$( oTabs[sCode] ).className = 'PopupTabSelected' ;
451
$( oTabs[sCode] ).className = 'PopupTab' ;
454
if ( typeof( window.frames["frmMain"].OnDialogTabChange ) == 'function' )
455
window.frames["frmMain"].OnDialogTabChange( tabCode ) ;
458
function TabDiv_OnClick()
460
setSelectedTab( this.TabCode ) ;
463
window.AddTab = function( tabCode, tabText, startHidden )
465
if ( typeof( oTabs[ tabCode ] ) != 'undefined' )
468
var eTabsRow = $( 'Tabs' ) ;
470
var oCell = eTabsRow.insertCell( eTabsRow.cells.length - 1 ) ;
471
oCell.noWrap = true ;
473
var oDiv = document.createElement( 'DIV' ) ;
474
oDiv.className = 'PopupTab' ;
475
oDiv.innerHTML = tabText ;
476
oDiv.TabCode = tabCode ;
477
oDiv.onclick = TabDiv_OnClick ;
478
oDiv.id = Math.random() ;
481
oDiv.style.display = 'none' ;
483
eTabsRow = $( 'TabsRow' ) ;
485
oCell.appendChild( oDiv ) ;
487
if ( eTabsRow.style.display == 'none' )
489
var eTitleArea = $( 'TitleArea' ) ;
490
eTitleArea.className = 'PopupTitle' ;
492
oDiv.className = 'PopupTabSelected' ;
493
eTabsRow.style.display = '' ;
495
if ( window.onresize )
499
oTabs[ tabCode ] = oDiv.id ;
501
FCKTools.DisableSelection( oDiv ) ;
504
window.SetSelectedTab = setSelectedTab ;
506
window.SetTabVisibility = function( tabCode, isVisible )
508
var oTab = $( oTabs[ tabCode ] ) ;
509
oTab.style.display = isVisible ? '' : 'none' ;
511
if ( ! isVisible && oTab.className == 'PopupTabSelected' )
513
for ( var sCode in oTabs )
515
if ( $( oTabs[sCode] ).style.display != 'none' )
517
setSelectedTab( sCode ) ;
525
// readystatechange handler for registering drag and drop handlers in cover
526
// iframes, defined out here to avoid memory leak.
527
// Do NOT put this function as a private function as it will induce memory leak
528
// in IE and it's not detectable with Drip or sIEve and undetectable leaks are
529
// really nasty (sigh).
530
var onReadyRegister = function()
532
if ( this.readyState != 'complete' )
534
DragAndDrop.RegisterHandlers( this.contentWindow ) ;
537
// The business logic of the dialog, dealing with operational things like
538
// dialog open/dialog close/enable/disable/etc.
541
var setOnKeyDown = function( targetDocument )
543
targetDocument.onkeydown = function ( e )
545
e = e || event || this.parentWindow.event ;
549
var oTarget = e.srcElement || e.target ;
550
if ( oTarget.tagName == 'TEXTAREA' )
563
var contextMenuBlocker = function( e )
565
var sTagName = e.target.tagName ;
566
if ( ! ( ( sTagName == "INPUT" && e.target.type == "text" ) || sTagName == "TEXTAREA" ) )
570
var disableContextMenu = function( targetDocument )
572
if ( FCKBrowserInfo.IsIE )
575
targetDocument.addEventListener( 'contextmenu', contextMenuBlocker, true ) ;
578
// Program entry point.
579
window.Init = function()
581
$( 'contents' ).dir = langDir;
583
// Start the throbber timer.
584
Throbber.Show( 1000 ) ;
586
Sizer.RefreshContainerSize() ;
589
FCKTools.DisableSelection( document.body ) ;
591
// Make the title area draggable.
592
var titleElement = $( 'header' ) ;
593
titleElement.onmousedown = DragAndDrop.MouseDownHandler ;
595
// Connect mousemove and mouseup events from dialog frame and outer window to dialog dragging logic.
596
DragAndDrop.RegisterHandlers( window ) ;
597
DragAndDrop.RegisterHandlers( Args().TopWindow ) ;
599
// Disable the previous dialog if it exists.
600
if ( ParentDialog() )
602
ParentDialog().contentWindow.SetEnabled( false ) ;
603
if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 )
605
var currentParent = ParentDialog() ;
606
while ( currentParent )
608
var blockerFrame = currentParent.contentWindow.$( 'blocker' ) ;
609
if ( blockerFrame.readyState == 'complete' )
610
DragAndDrop.RegisterHandlers( blockerFrame.contentWindow ) ;
612
blockerFrame.onreadystatechange = onReadyRegister ;
613
currentParent = ParentDialog( currentParent ) ;
618
var currentParent = ParentDialog() ;
619
while ( currentParent )
621
DragAndDrop.RegisterHandlers( currentParent.contentWindow ) ;
622
currentParent = ParentDialog( currentParent ) ;
627
// If this is the only dialog on screen, enable the background cover.
628
if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 )
630
var blockerFrame = FCKDialog.GetCover().firstChild ;
631
if ( blockerFrame.readyState == 'complete' )
632
DragAndDrop.RegisterHandlers( blockerFrame.contentWindow ) ;
634
blockerFrame.onreadystatechange = onReadyRegister;
637
// Add Enter/Esc hotkeys and disable context menu for the dialog.
638
setOnKeyDown( document ) ;
639
disableContextMenu( document ) ;
642
window.LoadInnerDialog = function()
644
if ( window.onresize )
647
// First of all, translate the dialog box contents.
648
E.FCKLanguageManager.TranslatePage( document ) ;
650
// Create the IFRAME that holds the dialog contents.
651
$( 'innerContents' ).innerHTML = '<iframe id="frmMain" src="' + Args().Page + '" name="frmMain" frameborder="0" width="100%" height="100%" scrolling="auto" style="visibility: hidden;" allowtransparency="true"><\/iframe>' ;
654
window.InnerDialogLoaded = function()
656
// If the dialog has been closed before the iframe is loaded, do nothing.
657
if ( !frameElement.parentNode )
662
var frmMain = $('frmMain') ;
663
var innerWindow = frmMain.contentWindow ;
664
var innerDoc = innerWindow.document ;
666
// Show the loaded iframe.
667
frmMain.style.visibility = '' ;
669
// Set the language direction.
670
innerDoc.documentElement.dir = langDir ;
672
// Sets the Skin CSS.
673
innerDoc.write( FCKTools.GetStyleHtml( FCKConfig.SkinDialogCSS ) ) ;
675
setOnKeyDown( innerDoc ) ;
676
disableContextMenu( innerDoc ) ;
678
Sizer.RefreshContainerSize();
680
DragAndDrop.RegisterHandlers( innerWindow ) ;
682
innerWindow.focus() ;
687
window.SetOkButton = function( showIt )
689
$('btnOk').style.visibility = ( showIt ? '' : 'hidden' ) ;
692
window.Ok = function()
694
Selection.EnsureSelection() ;
696
var frmMain = window.frames["frmMain"] ;
698
if ( frmMain.Ok && frmMain.Ok() )
704
window.Cancel = function( dontFireChange )
706
Selection.EnsureSelection() ;
707
return CloseDialog( dontFireChange ) ;
710
window.CloseDialog = function( dontFireChange )
714
// Points the src to a non-existent location to avoid loading errors later, in case the dialog
715
// haven't been completed loaded at this point.
716
if ( $( 'frmMain' ) )
717
$( 'frmMain' ).src = FCKTools.GetVoidUrl() ;
719
if ( !dontFireChange && !FCK.EditMode )
721
// All dialog windows, by default, will fire the "OnSelectionChange"
722
// event, no matter the Ok or Cancel button has been pressed.
723
// It seems that OnSelectionChange may enter on a concurrency state
724
// on some situations (#1965), so we should put the event firing in
725
// the execution queue instead of executing it immediately.
726
setTimeout( function()
728
FCK.Events.FireEvent( 'OnSelectionChange' ) ;
732
FCKDialog.OnDialogClose( window ) ;
735
window.SetEnabled = function( isEnabled )
737
var cover = $( 'cover' ) ;
738
cover.style.display = isEnabled ? 'none' : '' ;
740
if ( FCKBrowserInfo.IsIE && !FCKBrowserInfo.IsIE7 )
744
// Inser the blocker IFRAME before the cover.
745
var blocker = document.createElement( 'iframe' ) ;
746
blocker.src = FCKTools.GetVoidUrl() ;
747
blocker.hideFocus = true ;
748
blocker.frameBorder = 0 ;
749
blocker.id = blocker.className = 'blocker' ;
750
cover.appendChild( blocker ) ;
754
var blocker = $( 'blocker' ) ;
755
if ( blocker && blocker.parentNode )
756
blocker.parentNode.removeChild( blocker ) ;
764
<body onload="Init();" class="PopupBody">
765
<div class="contents" id="contents">
767
<div id="TitleArea" class="PopupTitle PopupTitleBorder">
768
<script type="text/javascript">
770
document.write( Args().Title ) ;
773
<div id="closeButton" onclick="Cancel();"></div>
775
<div id="TabsRow" class="PopupTabArea" style="display: none">
776
<table border="0" cellpadding="0" cellspacing="0" width="100%">
778
<td class="PopupTabEmptyArea"> </td>
779
<td class="PopupTabEmptyArea" width="100%"> </td>
784
<div id="innerContents"></div>
785
<div id="PopupButtons" class="PopupButtons">
786
<table border="0" cellpadding="0" cellspacing="0">
788
<td width="100%"> </td>
790
<input id="btnOk" style="visibility: hidden;" type="button" value="Ok" class="Button" onclick="Ok();" fckLang="DlgBtnOK" />
792
<input id="btnCancel" type="button" value="Cancel" class="Button" onclick="Cancel();" fckLang="DlgBtnCancel" />
798
<div class="tl"></div>
799
<div class="tc"></div>
800
<div class="tr"></div>
801
<div class="ml"></div>
802
<div class="mr"></div>
803
<div class="bl"></div>
804
<div class="bc"></div>
805
<div class="br"></div>
806
<div class="cover" id="cover" style="display:none"></div>
807
<div id="throbberBlock" style="position: absolute; visibility: hidden"></div>
808
<script type="text/javascript">
810
// Set the class name for language direction.
811
document.body.className += ' ' + langDir ;
813
var cover = $( 'cover' ) ;
814
cover.style.backgroundColor = FCKConfig.BackgroundBlockerColor ;
815
FCKDomTools.SetOpacity( cover, FCKConfig.BackgroundBlockerOpacity ) ;