rtehtmlarea_bugfix_13956_trunk.patch

Administrator Admin, 2010-04-08 01:39

Download (13.2 KB)

View differences:

typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js (copie de travail)
908 908
	 * Initialize event listeners and the document after the iframe has rendered
909 909
	 */
910 910
	initEventListeners: function () {
911
			// The editor iframe may become hidden with style.display = "none"
912
			// This breaks the editor in Firefox: the designMode attribute needs to be reset after the style.display of the containing div is reset to "block"
913
		if (Ext.isGecko && this.isNested) {
914
			Ext.each(this.nestedParentElements.sorted, function (nested) {
915
				this.mon(Ext.get(nested), 'DOMAttrModified', this.onNestedShow, this, {delay: 100});
916
			}, this);
917
		}
911
		this.initStyleChangeEventListener();
918 912
		if (Ext.isOpera) {
919 913
			this.mon(this.getEl(), 'load', this.initializeIframe , this, {single: true});
920 914
		} else {
......
922 916
		}
923 917
	},
924 918
	/*
919
	 * The editor iframe may become hidden with style.display = "none" on some parent div
920
	 * This breaks the editor in Firefox: the designMode attribute needs to be reset after the style.display of the container div is reset to "block"
921
	 * In all browsers, it breaks the evaluation of the framework dimensions
922
	 */
923
	initStyleChangeEventListener: function () {
924
		if (this.isNested  && !Ext.isWebKit) {
925
			Ext.each(this.nestedParentElements.sorted, function (nested) {
926
				this.mon(
927
					Ext.get(nested),
928
					Ext.isIE ? 'propertychange' : 'DOMAttrModified',
929
					this.onNestedShow,
930
					this,
931
					{
932
						delay: 50,
933
						single: true,
934
						stopEvent: true,
935
						target: Ext.get(nested)
936
					}
937
				);
938
			}, this);
939
		}
940
	},
941
	/*
925 942
	 * editorId should be set in config
926 943
	 */
927 944
	editorId: null,
......
1167 1184
	 */
1168 1185
	onNestedShow: function (event, target) {
1169 1186
		var styleEvent = true;
1170
			// In older versions of Mozilla ev.attrName is not yet set and refering to it causes a non-catchable crash
1171
			// We are assuming that this was fixed in Firefox 2.0.0.11
1172
		if (navigator.productSub > 20071127) {
1187
			// In older versions of Gecko attrName is not set and refering to it causes a non-catchable crash
1188
		if ((Ext.isGecko && navigator.productSub > 20071127) || Ext.isOpera) {
1173 1189
			styleEvent = (event.browserEvent.attrName == 'style');
1190
		} else if (Ext.isIE) {
1191
			styleEvent = (event.browserEvent.propertyName == 'style.display');
1174 1192
		}
1175
		if (styleEvent && this.nestedParentElements.sorted.indexOf(target.id) != -1 && this.getEditor().getMode() === 'wysiwyg' && (target.style.display == '' || target.style.display == 'block')) {
1176
				// Check if all affected nested elements are displayed (style.display!='none'):
1193
		if (styleEvent && this.nestedParentElements.sorted.indexOf(target.id) != -1 && (target.style.display == '' || target.style.display == 'block')) {
1194
				// Check if all container nested elements are displayed
1177 1195
			if (HTMLArea.util.TYPO3.allElementsAreDisplayed(this.nestedParentElements.sorted)) {
1178
				this.setDesignMode(true);
1179
				this.fireEvent('show');
1180
				this.getEditor().updateToolbar();
1196
				if (this.getEditor().getMode() === 'wysiwyg') {
1197
					if (Ext.isGecko) {
1198
						this.setDesignMode(true);
1199
					}
1200
					this.fireEvent('show');
1201
				} else {
1202
					this.ownerCt.textAreaContainer.fireEvent('show');
1203
				}
1204
				this.getToolbar().update();
1181 1205
			}
1182 1206
		}
1183
		event.stopEvent();
1207
		this.initStyleChangeEventListener();
1184 1208
	},
1185 1209
	/*
1186 1210
	 * Get the HTML content of the iframe
......
2124 2148
			// Make the framework resizable, if configured by the user
2125 2149
		this.makeResizable();
2126 2150
			// Monitor textArea container becoming shown or hidden as it may change the height of the status bar
2127
		this.mon(this.textAreaContainer, 'show', this.onTextAreaShow, this);
2128
		if (this.resizable) {
2129
				// Monitor iframe becoming shown or hidden as it may change the height of the status bar
2130
			this.mon(this.iframe, 'show', this.onIframeShow, this);
2131
		}
2151
		this.mon(this.textAreaContainer, 'show', this.resizable ? this.onTextAreaShow : this.onWindowResize, this);
2152
			// Monitor iframe becoming shown or hidden as it may change the height of the status bar
2153
		this.mon(this.iframe, 'show', this.resizable ? this.onIframeShow : this.onWindowResize, this);
2132 2154
			// Monitor window resizing
2133
		if (this.resizable || this.textAreaInitialSize.width.indexOf('%') !== -1) {
2134
			Ext.EventManager.onWindowResize(this.onWindowResize, this);
2135
		}
2155
		Ext.EventManager.onWindowResize(this.onWindowResize, this);
2136 2156
			// If the textarea is inside a form, on reset, re-initialize the HTMLArea content and update the toolbar
2137 2157
		var form = this.textArea.dom.form;
2138 2158
		if (form) {
......
2145 2165
			this.mon(Ext.get(form), 'reset', this.onReset, this);
2146 2166
		}
2147 2167
		this.addListener({
2168
			resize: {
2169
				fn: this.onFrameworkResize
2170
			},
2148 2171
			beforedestroy: {
2149 2172
				fn: this.onBeforeDestroy
2150 2173
			}
......
2199 2222
		height: 0
2200 2223
	},
2201 2224
	/*
2225
	 * doLayout will fail if inside a hidden tab or inline element
2226
	 */
2227
	doLayout: function () {
2228
		if (!this.isNested || HTMLArea.util.TYPO3.allElementsAreDisplayed(this.nestedParentElements.sorted)) {
2229
			HTMLArea.Framework.superclass.doLayout.call(this);
2230
		} else {
2231
				// Clone the array of nested tabs and inline levels instead of using a reference as HTMLArea.util.TYPO3.accessParentElements will modify the array
2232
			var parentElements = [].concat(this.nestedParentElements.sorted);
2233
				// Walk through all nested tabs and inline levels to get correct sizes
2234
			HTMLArea.util.TYPO3.accessParentElements(parentElements, 'HTMLArea.Framework.superclass.doLayout.call(args[0])', [this]);
2235
		}
2236
	},
2237
	/*
2202 2238
	 * Make the framework resizable, if configured
2203 2239
	 */
2204 2240
	makeResizable: function () {
......
2213 2249
		}
2214 2250
	},
2215 2251
	/*
2252
	 * Resize the framework when the resizer handles are used
2253
	 */
2254
	onHtmlAreaResize: function (resizer, width, height, event) {
2255
			// Set width first as it may change the height of the toolbar and of the statusBar
2256
		this.setWidth(width);
2257
			// Set height of iframe and textarea
2258
		this.iframe.setHeight(this.getInnerHeight());
2259
		this.textArea.setSize(this.getInnerWidth(), this.getInnerHeight());
2260
	},
2261
	/*
2216 2262
	 * Size the iframe according to initial textarea size as set by Page and User TSConfig
2217 2263
	 */
2218
	onWindowResize: function(width, height) {
2264
	onWindowResize: function (width, height) {
2219 2265
		if (!this.isNested || HTMLArea.util.TYPO3.allElementsAreDisplayed(this.nestedParentElements.sorted)) {
2220 2266
			this.resizeFramework(width, height);
2221 2267
		} else {
......
2229 2275
	 * Resize the framework to its initial size
2230 2276
	 */
2231 2277
	resizeFramework: function (width, height) {
2232
		var frameworkHeight = this.fullScreen ? HTMLArea.util.TYPO3.getWindowSize().height - 20 : parseInt(this.textAreaInitialSize.height);
2278
		var frameworkHeight = parseInt(this.textAreaInitialSize.height);
2233 2279
		if (this.textAreaInitialSize.width.indexOf('%') === -1) {
2234 2280
				// Width is specified in pixels
2235 2281
			var frameworkWidth = parseInt(this.textAreaInitialSize.width) - this.getFrameWidth();
2236 2282
		} else {
2237 2283
				// Width is specified in %
2238
			if (Ext.isDefined(width)) {
2284
			if (Ext.isNumber(width)) {
2239 2285
					// Framework sizing on actual window resize
2240
				var frameworkWidth = parseInt(((width - this.textAreaInitialSize.nextSiblingWidth - (this.fullScreen ? 10 : Ext.getScrollBarWidth()) - this.getBox().x - 15) * parseInt(this.textAreaInitialSize.width))/100);
2286
				var frameworkWidth = parseInt(((width - this.textAreaInitialSize.wizardsWidth - (this.fullScreen ? 10 : Ext.getScrollBarWidth()) - this.getBox().x - 15) * parseInt(this.textAreaInitialSize.width))/100);
2241 2287
			} else {
2242 2288
					// Initial framework sizing
2243
				var frameworkWidth = parseInt(((HTMLArea.util.TYPO3.getWindowSize().width - this.textAreaInitialSize.nextSiblingWidth - (this.fullScreen ? 10 : Ext.getScrollBarWidth()) - this.getBox().x - 15) * parseInt(this.textAreaInitialSize.width))/100);
2289
				var frameworkWidth = parseInt(((HTMLArea.util.TYPO3.getWindowSize().width - this.textAreaInitialSize.wizardsWidth - (this.fullScreen ? 10 : Ext.getScrollBarWidth()) - this.getBox().x - 15) * parseInt(this.textAreaInitialSize.width))/100);
2244 2290
			}
2245 2291
		}
2246 2292
		if (this.resizable) {
2247 2293
			this.resizer.resizeTo(frameworkWidth, frameworkHeight);
2248 2294
		} else {
2249 2295
			this.setSize(frameworkWidth, frameworkHeight);
2250
				// Adjust height of iframe and textarea to height of toolbar and statusbar
2251
			this.iframe.setSize(this.getInnerWidth(), this.getInnerHeight());
2252
			this.textArea.setSize(this.getInnerWidth(), this.getInnerHeight());
2253 2296
		}
2254 2297
	},
2255 2298
	/*
2256
	 * Resize the components when the editor framework was resized
2299
	 * Resize the framework components
2257 2300
	 */
2258
	onHtmlAreaResize: function (resizer, width, height, event) {
2259
			// Set width first as it may change the height of the toolbar and of the statusBar
2260
		this.setWidth(width);
2261
			// Set height of iframe and textarea
2262
		this.iframe.setHeight(this.getInnerHeight());
2301
	onFrameworkResize: function () {
2302
		this.iframe.setSize(this.getInnerWidth(), this.getInnerHeight());
2263 2303
		this.textArea.setSize(this.getInnerWidth(), this.getInnerHeight());
2264 2304
	},
2265 2305
	/*
......
2273 2313
	 * Adjust the height to the changing size of the statusbar when the iframe is shown
2274 2314
	 */
2275 2315
	onIframeShow: function () {
2276
		this.iframe.setHeight(this.getInnerHeight());
2277
		this.textArea.setHeight(this.getInnerHeight());
2316
		if (this.getInnerHeight() <= 0) {
2317
			this.onWindowResize();
2318
		} else {
2319
			this.iframe.setHeight(this.getInnerHeight());
2320
			this.textArea.setHeight(this.getInnerHeight());
2321
		}
2278 2322
	},
2279 2323
	/*
2280 2324
	 * Fire the editor when all components of the framework are rendered and ready
......
2313 2357
	 * Cleanup on framework destruction
2314 2358
	 */
2315 2359
	onBeforeDestroy: function () {
2316
		if (this.resizable) {
2317
			Ext.EventManager.removeResizeListener(this.onWindowResize, this);
2318
		}
2360
		Ext.EventManager.removeResizeListener(this.onWindowResize, this);
2319 2361
		var form = this.textArea.dom.form;
2320 2362
		if (form) {
2321 2363
			form.htmlAreaPreviousOnReset = null;
......
2342 2384
		this.textAreaInitialSize = {
2343 2385
			width: this.config.RTEWidthOverride ? this.config.RTEWidthOverride : this.textArea.getStyle('width'),
2344 2386
			height: this.config.fullScreen ? HTMLArea.util.TYPO3.getWindowSize().height - 20 : this.textArea.getStyle('height'),
2345
			nextSiblingWidth: 0
2387
			wizardsWidth: 0
2346 2388
		};
2347 2389
			// TYPO3 Inline elements and tabs
2348 2390
		this.nestedParentElements = {
......
2351 2393
		};
2352 2394
		this.isNested = !Ext.isEmpty(this.nestedParentElements.sorted);
2353 2395
			// Get width of wizards
2354
		var nextSibling = this.textArea.parent().parent().next();
2355
		if (nextSibling) {
2396
		this.wizards = this.textArea.parent().parent().next();
2397
		if (this.wizards) {
2356 2398
			if (!this.isNested || HTMLArea.util.TYPO3.allElementsAreDisplayed(this.nestedParentElements.sorted)) {
2357
				this.textAreaInitialSize.nextSiblingWidth = nextSibling.getWidth();
2399
				this.textAreaInitialSize.wizardsWidth = this.wizards.getWidth();
2358 2400
			} else {
2359 2401
					// Clone the array of nested tabs and inline levels instead of using a reference as HTMLArea.util.TYPO3.accessParentElements will modify the array
2360 2402
				var parentElements = [].concat(this.nestedParentElements.sorted);
2361 2403
					// Walk through all nested tabs and inline levels to get correct size
2362
					this.textAreaInitialSize.nextSiblingWidth = HTMLArea.util.TYPO3.accessParentElements(parentElements, 'args[0].getWidth()', [nextSibling]);
2404
				this.textAreaInitialSize.wizardsWidth = HTMLArea.util.TYPO3.accessParentElements(parentElements, 'args[0].getWidth()', [this.wizards]);
2363 2405
			}
2364 2406
		}
2407
			// Hide the wizards so that they do not move around while the editor framework is being sized
2408
		this.wizards.hide();
2365 2409
			// Plugins register
2366 2410
		this.plugins = {};
2367 2411
			// Register the plugins included in the configuration
......
2478 2522
		this.generatePlugins();
2479 2523
			// Make the editor visible
2480 2524
		this.show();
2525
			// Make the wizards visible again
2526
		this.wizards.show();
2481 2527
			// Focus on the first editor that is not hidden
2482 2528
		Ext.iterate(RTEarea, function (editorId, RTE) {
2483 2529
			if (!Ext.isDefined(RTE.editor) || (RTE.editor.isNested && !HTMLArea.util.TYPO3.allElementsAreDisplayed(RTE.editor.nestedParentElements.sorted))) {
......
2697 2743
			var result = {};
2698 2744
			if (parentElements.length) {
2699 2745
				var currentElement = parentElements.pop();
2700
				var elementStyle = document.getElementById(currentElement).style;
2701
				var actionRequired = (elementStyle.display == 'none' ? true : false);
2746
				currentElement = Ext.get(currentElement);
2747
				var actionRequired = (currentElement.getStyle('display') == 'none');
2702 2748
				if (actionRequired) {
2703
					var originalVisibility = elementStyle.visibility;
2704
					var originalPosition = elementStyle.position;
2705
					elementStyle.visibility = 'hidden';
2706
					elementStyle.position = 'absolute';
2707
					elementStyle.display = '';
2749
					var originalStyles = currentElement.getStyles('visibility', 'position', 'top', 'display');
2750
					currentElement.setStyle({
2751
						visibility: 'hidden',
2752
						position: 'absolute',
2753
						top: '-10000px',
2754
						display: ''
2755
					});
2708 2756
				}
2709 2757
				result = this.accessParentElements(parentElements, callbackFunc, args);
2710 2758
				if (actionRequired) {
2711
					elementStyle.display = 'none';
2712
					elementStyle.position = originalPosition;
2713
					elementStyle.visibility = originalVisibility;
2759
					currentElement.setStyle(originalStyles);
2714 2760
				}
2715 2761
			} else {
2716 2762
				result = eval(callbackFunc);