Index: typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js (révision 9247)
+++ typo3/sysext/rtehtmlarea/htmlarea/htmlarea-gecko.js (copie de travail)
@@ -481,13 +481,13 @@
} else {
var spans = node.getElementsByTagName("span");
for (var i = spans.length; --i >= 0;) {
- if (HTMLArea._hasClass(spans[i], "Apple-style-span")) {
+ if (HTMLArea.DOM.hasClass(spans[i], "Apple-style-span")) {
this.removeMarkup(spans[i]);
}
}
var fonts = node.getElementsByTagName("font");
for (i = fonts.length; --i >= 0;) {
- if (HTMLArea._hasClass(fonts[i], "Apple-style-span")) {
+ if (HTMLArea.DOM.hasClass(fonts[i], "Apple-style-span")) {
this.removeMarkup(fonts[i]);
}
}
Index: typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js (révision 9247)
+++ typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js (copie de travail)
@@ -36,10 +36,7 @@
// Avoid re-initialization on AJax call when HTMLArea object was already initialized
if (typeof(HTMLArea) == 'undefined') {
// Establish HTMLArea name space
-Ext.namespace('HTMLArea.util.TYPO3', 'HTMLArea.util.Tips', 'HTMLArea.util.Color', 'Ext.ux.form', 'Ext.ux.menu', 'Ext.ux.Toolbar');
-/***************************************************
- * CONSTANTS
- ***************************************************/
+Ext.namespace('HTMLArea.CSS', 'HTMLArea.util.TYPO3', 'HTMLArea.util.Tips', 'HTMLArea.util.Color', 'Ext.ux.form', 'Ext.ux.menu', 'Ext.ux.Toolbar');
Ext.apply(HTMLArea, {
/*************************************************************************
* THESE BROWSER IDENTIFICATION CONSTANTS ARE DEPRECATED AS OF TYPO3 4.4 *
@@ -51,7 +48,9 @@
is_safari : Ext.isWebKit,
is_chrome : Ext.isChrome,
is_opera : Ext.isOpera,
- // Compile some regular expressions
+ /***************************************************
+ * COMPILED REGULAR EXPRESSIONS *
+ ***************************************************/
RE_htmlTag : /<.[^<>]*?>/g,
RE_tagName : /(<\/|<)\s*([^ \t\n>]+)/ig,
RE_head : /
((.|\n)*?)<\/head>/i,
@@ -63,39 +62,48 @@
RE_blockTags : /^(body|p|h1|h2|h3|h4|h5|h6|ul|ol|pre|dl|dt|dd|div|noscript|blockquote|form|hr|table|caption|fieldset|address|td|tr|th|li|tbody|thead|tfoot|iframe)$/i,
RE_closingTags : /^(p|blockquote|a|li|ol|ul|dl|dt|td|th|tr|tbody|thead|tfoot|caption|colgroup|table|div|b|bdo|big|cite|code|del|dfn|em|i|ins|kbd|label|q|samp|small|span|strike|strong|sub|sup|tt|u|var|abbr|acronym|font|center|object|embed|style|script|title|head)$/i,
RE_noClosingTag : /^(img|br|hr|col|input|area|base|link|meta|param)$/i,
- RE_numberOrPunctuation : /[0-9.(),;:!¡?¿%#$'"_+=\\\/-]*/g
-});
-/***************************************************
- * TROUBLESHOOTING
- ***************************************************/
-HTMLArea._appendToLog = function(str){
- if (HTMLArea.enableDebugMode) {
- var log = document.getElementById('HTMLAreaLog');
- if(log) {
- log.appendChild(document.createTextNode(str));
- log.appendChild(document.createElement('br'));
+ RE_numberOrPunctuation : /[0-9.(),;:!¡?¿%#$'"_+=\\\/-]*/g,
+ /***************************************************
+ * TROUBLESHOOTING *
+ ***************************************************/
+ _appendToLog: function(str){
+ if (HTMLArea.enableDebugMode) {
+ var log = document.getElementById('HTMLAreaLog');
+ if(log) {
+ log.appendChild(document.createTextNode(str));
+ log.appendChild(document.createElement('br'));
+ }
}
+ },
+ appendToLog: function (editorId, objectName, functionName, text) {
+ HTMLArea._appendToLog(editorId + '[' + objectName + '::' + functionName + ']: ' + text);
+ },
+ /***************************************************
+ * LOCALIZATION *
+ ***************************************************/
+ localize: function (label) {
+ return HTMLArea.I18N.dialogs[label] || HTMLArea.I18N.tooltips[label] || HTMLArea.I18N.msg[label] || label;
+ },
+ /***************************************************
+ * INITIALIZATION *
+ ***************************************************/
+ init: function () {
+ // Apply global configuration settings
+ Ext.apply(HTMLArea, RTEarea[0]);
+ Ext.applyIf(HTMLArea, {
+ editorSkin : HTMLArea.editorUrl + 'skins/default/',
+ editorCSS : HTMLArea.editorUrl + 'skins/default/htmlarea.css'
+ });
+ if (!Ext.isString(HTMLArea.editedContentCSS)) {
+ HTMLArea.editedContentCSS = HTMLArea.editorSkin + 'htmlarea-edited-content.css';
+ }
+ HTMLArea.isReady = true;
+ HTMLArea._appendToLog("[HTMLArea::init]: Editor url set to: " + HTMLArea.editorUrl);
+ HTMLArea._appendToLog("[HTMLArea::init]: Editor skin CSS set to: " + HTMLArea.editorCSS);
+ HTMLArea._appendToLog("[HTMLArea::init]: Editor content skin CSS set to: " + HTMLArea.editedContentCSS);
}
-};
+});
/***************************************************
- * HTMLArea INITIALIZATION
- ***************************************************/
-HTMLArea.init = function() {
- // Apply global configuration settings
- Ext.apply(HTMLArea, RTEarea[0]);
- Ext.applyIf(HTMLArea, {
- editorSkin : HTMLArea.editorUrl + 'skins/default/',
- editorCSS : HTMLArea.editorUrl + 'skins/default/htmlarea.css'
- });
- if (!Ext.isString(HTMLArea.editedContentCSS)) {
- HTMLArea.editedContentCSS = HTMLArea.editorSkin + 'htmlarea-edited-content.css';
- }
- HTMLArea.isReady = true;
- HTMLArea._appendToLog("[HTMLArea::init]: Editor url set to: " + HTMLArea.editorUrl);
- HTMLArea._appendToLog("[HTMLArea::init]: Editor skin CSS set to: " + HTMLArea.editorCSS);
- HTMLArea._appendToLog("[HTMLArea::init]: Editor content skin CSS set to: " + HTMLArea.editedContentCSS);
-};
-/***************************************************
* EDITOR CONFIGURATION
***************************************************/
HTMLArea.Config = function (editorId) {
@@ -2085,6 +2093,10 @@
this.registerPlugin(plugin);
}
}, this);
+ // Create Ajax object
+ this.ajax = new HTMLArea.Ajax({
+ editor: this
+ });
// Initialize keyboard input inhibit flag
this.inhibitKeyboardInput = false;
this.addEvents(
@@ -2423,6 +2435,17 @@
document.getElementById('editorWrap' + this.editorId).style.visibility = 'visible';
},
/*
+ * Append an entry at the end of the troubleshooting log
+ *
+ * @param string functionName: the name of the editor function writing to the log
+ * @param string text: the text of the message
+ *
+ * @return void
+ */
+ appendToLog: function (objectName, functionName, text) {
+ HTMLArea.appendToLog(this.editorId, objectName, functionName, text);
+ },
+ /*
* Iframe unload handler: Update the textarea for submission and cleanup
*/
onUnload: function (event) {
@@ -2450,6 +2473,83 @@
RTEarea[this.editorId].editor = null;
}
});
+HTMLArea.Ajax = function (config) {
+ Ext.apply(this, config);
+};
+HTMLArea.Ajax = Ext.extend(HTMLArea.Ajax, {
+ /*
+ * Load a Javascript file asynchronously
+ *
+ * @param string url: url of the file to load
+ * @param function callBack: the callBack function
+ * @param object scope: scope of the callbacks
+ *
+ * @return boolean true on success of the request submission
+ */
+ getJavascriptFile: function (url, callback, scope) {
+ var success = false;
+ var self = this;
+ this.editor.appendToLog('HTMLArea.Ajax', 'getJavascriptFile', 'Requesting script ' + url);
+ Ext.Ajax.request({
+ method: 'GET',
+ url: url,
+ callback: callback,
+ success: function (response) {
+ success = true;
+ },
+ failure: function (response) {
+ self.editor.inhibitKeyboardInput = false;
+ self.editor.appendToLog('HTMLArea.Ajax', 'getJavascriptFile', 'Unable to get ' + url + ' . Server reported ' + response.status);
+ },
+ scope: scope
+ });
+ return success;
+ },
+ /*
+ * Post data to the server
+ *
+ * @param string url: url to post data to
+ * @param object data: data to be posted
+ * @param function callback: function that will handle the response returned by the server
+ * @param object scope: scope of the callbacks
+ *
+ * @return boolean true on success
+ */
+ postData: function (url, data, callback, scope) {
+ var success = false;
+ var self = this;
+ data.charset = this.editor.config.typo3ContentCharset ? this.editor.config.typo3ContentCharset : 'utf-8';
+ var params = '';
+ Ext.iterate(data, function (parameter, value) {
+ params += (params.length ? '&' : '') + parameter + '=' + encodeURIComponent(value);
+ });
+ params += this.editor.config.RTEtsConfigParams;
+ this.editor.appendToLog('HTMLArea.Ajax', 'postData', 'Posting to ' + url + '. Data: ' + params);
+ Ext.Ajax.request({
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
+ },
+ url: url,
+ params: params,
+ callback: Ext.isFunction(callback) ? callback: function (options, success, response) {
+ if (success) {
+ self.editor.appendToLog('HTMLArea.Ajax', 'postData', 'Post request to ' + url + ' successful. Server response: ' + response.responseText);
+ } else {
+ self.editor.appendToLog('HTMLArea.Ajax', 'postData', 'Post request to ' + url + ' failed. Server reported ' + response.status);
+ }
+ },
+ success: function (response) {
+ success = true;
+ },
+ failure: function (response) {
+ self.editor.appendToLog('HTMLArea.Ajax', 'postData', 'Unable to post ' + url + ' . Server reported ' + response.status);
+ },
+ scope: scope
+ });
+ return success;
+ }
+});
/***************************************************
* HTMLArea.util.TYPO3: Utility functions for dealing with tabs and inline elements in TYPO3 forms
***************************************************/
@@ -2929,7 +3029,6 @@
HTMLArea.checkSupportedBrowser = function() {
return Ext.isGecko || Ext.isWebKit || Ext.isOpera || Ext.isIE;
};
-
/*
* Remove a class name from the class attribute of an element
*
@@ -2937,51 +3036,22 @@
* @param string className: the class name to remove
* @param boolean substring: if true, remove the first class name starting with the given string
* @return void
+ ***********************************************
+ * THIS FUNCTION IS DEPRECATED AS OF TYPO3 4.5 *
+ ***********************************************
*/
HTMLArea._removeClass = function(el, className, substring) {
- if (!el || !el.className) return;
- var classes = el.className.trim().split(" ");
- var newClasses = new Array();
- for (var i = classes.length; --i >= 0;) {
- if (!substring) {
- if (classes[i] != className) {
- newClasses[newClasses.length] = classes[i];
- }
- } else if (classes[i].indexOf(className) != 0) {
- newClasses[newClasses.length] = classes[i];
- }
- }
- if (newClasses.length == 0) {
- if (!Ext.isOpera) {
- el.removeAttribute("class");
- if (Ext.isIE) {
- el.removeAttribute("className");
- }
- } else {
- el.className = '';
- }
- } else {
- el.className = newClasses.join(" ");
- }
+ HTMLArea.DOM.removeClass(el, className, substring);
};
-
/*
* Add a class name to the class attribute
+ ***********************************************
+ * THIS FUNCTION IS DEPRECATED AS OF TYPO3 4.5 *
+ ***********************************************
*/
-HTMLArea._addClass = function(el, addClassName) {
- HTMLArea._removeClass(el, addClassName);
- if (el.className && HTMLArea.classesXOR && HTMLArea.classesXOR.hasOwnProperty(addClassName) && typeof(HTMLArea.classesXOR[addClassName].test) == "function") {
- var classNames = el.className.trim().split(" ");
- for (var i = classNames.length; --i >= 0;) {
- if (HTMLArea.classesXOR[addClassName].test(classNames[i])) {
- HTMLArea._removeClass(el, classNames[i]);
- }
- }
- }
- if (el.className) el.className += " " + addClassName;
- else el.className = addClassName;
+HTMLArea._addClass = function(el, className) {
+ HTMLArea.DOM.addClass(el, className);
};
-
/*
* Check if a class name is in the class attribute of an element
*
@@ -2989,14 +3059,12 @@
* @param string className: the class name to look for
* @param boolean substring: if true, look for a class name starting with the given string
* @return boolean true if the class name was found
+ ***********************************************
+ * THIS FUNCTION IS DEPRECATED AS OF TYPO3 4.5 *
+ ***********************************************
*/
HTMLArea._hasClass = function(el, className, substring) {
- if (!el || !el.className) return false;
- var classes = el.className.trim().split(" ");
- for (var i = classes.length; --i >= 0;) {
- if (classes[i] == className || (substring && classes[i].indexOf(className) == 0)) return true;
- }
- return false;
+ return HTMLArea.DOM.hasClass(el, className, substring);
};
HTMLArea.isBlockElement = function(el) { return el && el.nodeType == 1 && HTMLArea.RE_blockTags.test(el.nodeName.toLowerCase()); };
@@ -3069,11 +3137,11 @@
/*****************************************************************
* HTMLArea.DOM: Utility functions for dealing with the DOM tree *
*****************************************************************/
-/***************************************************
- * DOM-RELATED CONSTANTS
- ***************************************************/
HTMLArea.DOM = function () {
return {
+ /***************************************************
+ * DOM-RELATED CONSTANTS
+ ***************************************************/
// DOM node types
ELEMENT_NODE: 1,
ATTRIBUTE_NODE: 2,
@@ -3086,7 +3154,110 @@
DOCUMENT_NODE: 9,
DOCUMENT_TYPE_NODE: 10,
DOCUMENT_FRAGMENT_NODE: 11,
- NOTATION_NODE: 12
+ NOTATION_NODE: 12,
+ /*
+ * Gets the class names assigned to a node, reserved classes removed
+ *
+ * @param object node: the node
+ * @return array array of class names on the node, reserved classes removed
+ */
+ getClassNames: function (node) {
+ var classNames = [];
+ if (node) {
+ if (node.className && /\S/.test(node.className)) {
+ classNames = node.className.trim().split(' ');
+ }
+ if (HTMLArea.reservedClassNames.test(node.className)) {
+ var cleanClassNames = [];
+ var j = -1;
+ for (var i = 0; i < classNames.length; ++i) {
+ if (!HTMLArea.reservedClassNames.test(classNames[i])) {
+ cleanClassNames[++j] = classNames[i];
+ }
+ }
+ classNames = cleanClassNames;
+ }
+ }
+ return classNames;
+ },
+ /*
+ * Check if a class name is in the class attribute of a node
+ *
+ * @param object node: the node
+ * @param string className: the class name to look for
+ * @param boolean substring: if true, look for a class name starting with the given string
+ * @return boolean true if the class name was found, false otherwise
+ */
+ hasClass: function (node, className, substring) {
+ var found = false;
+ if (node && node.className) {
+ var classes = node.className.trim().split(' ');
+ for (var i = classes.length; --i >= 0;) {
+ found = ((classes[i] == className) || (substring && classes[i].indexOf(className) == 0));
+ if (found) {
+ break;
+ }
+ }
+ }
+ return found;
+ },
+ /*
+ * Add a class name to the class attribute of a node
+ *
+ * @param object node: the node
+ * @param string className: the name of the class to be added
+ * @return void
+ */
+ addClass: function (node, className) {
+ if (node) {
+ HTMLArea.DOM.removeClass(node, className);
+ // Remove classes configured to be incompatible with the class to be added
+ if (node.className && HTMLArea.classesXOR && HTMLArea.classesXOR[className] && Ext.isFunction(HTMLArea.classesXOR[className].test)) {
+ var classNames = node.className.trim().split(' ');
+ for (var i = classNames.length; --i >= 0;) {
+ if (HTMLArea.classesXOR[className].test(classNames[i])) {
+ HTMLArea.DOM.removeClass(node, classNames[i]);
+ }
+ }
+ }
+ if (node.className) {
+ node.className += ' ' + className;
+ } else {
+ node.className = className;
+ }
+ }
+ },
+ /*
+ * Remove a class name from the class attribute of a node
+ *
+ * @param object node: the node
+ * @param string className: the class name to removed
+ * @param boolean substring: if true, remove the class names starting with the given string
+ * @return void
+ */
+ removeClass: function (node, className, substring) {
+ if (node && node.className) {
+ var classes = node.className.trim().split(' ');
+ var newClasses = [];
+ for (var i = classes.length; --i >= 0;) {
+ if ((!substring && classes[i] != className) || (substring && classes[i].indexOf(className) != 0)) {
+ newClasses[newClasses.length] = classes[i];
+ }
+ }
+ if (newClasses.length) {
+ node.className = newClasses.join(' ');
+ } else {
+ if (!Ext.isOpera) {
+ node.removeAttribute('class');
+ if (Ext.isIE) {
+ node.removeAttribute('className');
+ }
+ } else {
+ node.className = '';
+ }
+ }
+ }
+ }
};
}();
/***************************************************
@@ -3101,7 +3272,7 @@
keepTags: /.*/i,
removeAttributes: /none/i,
removeTrailingBR: true
- }
+ };
Ext.apply(this, config, configDefaults);
};
HTMLArea.DOM.Walker = Ext.extend(HTMLArea.DOM.Walker, {
@@ -3303,6 +3474,304 @@
}
});
/***************************************************
+ * HTMLArea.CSS.Parser: CSS Parser
+ ***************************************************/
+HTMLArea.CSS.Parser = Ext.extend(Ext.util.Observable, {
+ /*
+ * HTMLArea.CSS.Parser constructor
+ */
+ constructor: function (config) {
+ HTMLArea.CSS.Parser.superclass.constructor.call(this, {});
+ var configDefaults = {
+ parseAttemptsMaximumNumber: 17,
+ prefixLabelWithClassName: false,
+ postfixLabelWithClassName: false,
+ showTagFreeClasses: false,
+ tags: null,
+ editor: null
+ };
+ Ext.apply(this, config, configDefaults);
+ this.addEvents(
+ /*
+ * @event HTMLAreaEventCssParsingComplete
+ * Fires when parsing of the stylesheets of the iframe is complete
+ */
+ 'HTMLAreaEventCssParsingComplete'
+ );
+ },
+ /*
+ * The parsed classes
+ */
+ parsedClasses: {},
+ /*
+ * Boolean indicating whether are not parsing is complete
+ */
+ isReady: false,
+ /*
+ * Boolean indicating whether or not the stylesheets were accessible
+ */
+ cssLoaded: false,
+ /*
+ * Counter of the number of attempts at parsing the stylesheets
+ */
+ parseAttemptsCounter: 0,
+ /*
+ * Parsing attempt timeout id
+ */
+ attemptTimeout: null,
+ /*
+ * The error that occurred on the last attempt at parsing the stylesheets
+ */
+ error: null,
+ /*
+ * This function gets the parsed css classes
+ *
+ * @return object this.parsedClasses
+ */
+ getClasses: function() {
+ return this.parsedClasses;
+ },
+ /*
+ * This function initiates parsing of the stylesheets
+ *
+ * @return void
+ */
+ initiateParsing: function () {
+ if (this.editor.config.classesUrl && (typeof(HTMLArea.classesLabels) === 'undefined')) {
+ this.editor.ajax.getJavascriptFile(this.editor.config.classesUrl, function (options, success, response) {
+ if (success) {
+ try {
+ if (typeof(HTMLArea.classesLabels) === 'undefined') {
+ eval(response.responseText);
+ this.editor.appendToLog('HTMLArea.CSS.Parser', 'initiateParsing', 'Javascript file successfully evaluated: ' + this.editor.config.classesUrl);
+ }
+ } catch(e) {
+ this.editor.appendToLog('HTMLArea.CSS.Parser', 'initiateParsing', 'Error evaluating contents of Javascript file: ' + this.editor.config.classesUrl);
+ }
+ }
+ this.parse();
+ }, this);
+ } else {
+ this.parse();
+ }
+ },
+ /*
+ * This function parses the stylesheets of the iframe set in config
+ *
+ * @return void parsed css classes are accumulated in this.parsedClasses
+ */
+ parse: function() {
+ if (this.editor.document) {
+ this.parseStyleSheets();
+ if (!this.cssLoaded) {
+ if (this.parseAttemptsCounter < this.parseAttemptsMaximumNumber) {
+ this.attemptTimeout = this.parse.defer(200, this);
+ this.parseAttemptsCounter++;
+ } else {
+ this.editor.appendToLog('HTMLArea.CSS.Parser', 'parse', 'The stylesheets could not be parsed. Reported error: ' + this.error);
+ this.fireEvent('HTMLAreaEventCssParsingComplete');
+ }
+ } else {
+ this.attemptTimeout = null;
+ this.isReady = true;
+ this.filterAllowedClasses();
+ this.sort();
+ this.fireEvent('HTMLAreaEventCssParsingComplete');
+ }
+ }
+ },
+ /*
+ * This function parses the stylesheets of an iframe
+ *
+ * @return void parsed css classes are accumulated in this.parsedClasses
+ */
+ parseStyleSheets: function () {
+ this.cssLoaded = true;
+ this.error = null;
+ for (var i = 0; i < this.editor.document.styleSheets.length; i++) {
+ if (!Ext.isIE) {
+ try {
+ this.parseRules(this.editor.document.styleSheets[i].cssRules);
+ } catch (e) {
+ this.error = e;
+ this.cssLoaded = false;
+ this.parsedClasses = {};
+ }
+ } else {
+ try{
+ if (this.editor.document.styleSheets[i].imports) {
+ this.parseIeRules(this.editor.document.styleSheets[i].imports);
+ }
+ if (this.editor.document.styleSheets[i].rules) {
+ this.parseRules(this.editor.document.styleSheets[i].rules);
+ }
+ } catch (e) {
+ this.error = e;
+ this.cssLoaded = false;
+ this.parsedClasses = {};
+ }
+ }
+ }
+ },
+ /*
+ * This function parses the set of rules from a standard stylesheet
+ *
+ * @param array cssRules: the array of rules of a stylesheet
+ * @return void
+ */
+ parseRules: function (cssRules) {
+ for (var rule = 0; rule < cssRules.length; rule++) {
+ // Style rule
+ if (cssRules[rule].selectorText) {
+ this.parseSelectorText(cssRules[rule].selectorText);
+ } else {
+ // Import rule
+ if (cssRules[rule].styleSheet) {
+ this.parseRules(cssRules[rule].styleSheet.cssRules);
+ }
+ // Media rule
+ if (cssRules[rule].cssRules) {
+ this.parseRules(cssRules[rule].cssRules);
+ }
+ }
+ }
+ },
+ /*
+ * This function parses the set of rules from an IE stylesheet
+ *
+ * @param array cssRules: the array of rules of a stylesheet
+ * @return void
+ */
+ parseIeRules: function (cssRules) {
+ for (var rule = 0; rule < cssRules.length; rule++) {
+ // Import rule
+ if (cssRules[rule].imports) {
+ this.parseIeRules(cssRules[rule].imports);
+ }
+ // Style rule
+ if (cssRules[rule].rules) {
+ this.parseRules(cssRules[rule].rules);
+ }
+ }
+ },
+ /*
+ * This function parses a selector rule
+ *
+ * @param string selectorText: the text of the rule to parsed
+ * @return void
+ */
+ parseSelectorText: function (selectorText) {
+ var cssElements = [],
+ cssElement = [],
+ nodeName, className,
+ pattern = /(\S*)\.(\S+)/;
+ if (selectorText.search(/:+/) == -1) {
+ // Split equal styles
+ cssElements = selectorText.split(',');
+ for (var k = 0; k < cssElements.length; k++) {
+ // Match all classes (.) in selector rule
+ var s = cssElements[k], index;
+ while ((index = s.search(pattern)) > -1) {
+ var match = pattern.exec(s.substring(index));
+ s = s.substring(index+match[0].length);
+ nodeName = (match[1] && (match[1] != '*')) ? match[1].toLowerCase().trim() : 'all';
+ className = match[2];
+ if (className && !HTMLArea.reservedClassNames.test(className)) {
+ if (((nodeName != 'all') && (!this.tags || !this.tags[nodeName]))
+ || ((nodeName == 'all') && (!this.tags || !this.tags[nodeName]) && this.showTagFreeClasses)
+ || (this.tags && this.tags[nodeName] && this.tags[nodeName].allowedClasses && this.tags[nodeName].allowedClasses.test(className))) {
+ if (!this.parsedClasses[nodeName]) {
+ this.parsedClasses[nodeName] = {};
+ }
+ cssName = className;
+ if (HTMLArea.classesLabels && HTMLArea.classesLabels[className]) {
+ cssName = this.prefixLabelWithClassName ? (className + ' - ' + HTMLArea.classesLabels[className]) : HTMLArea.classesLabels[className];
+ cssName = this.postfixLabelWithClassName ? (cssName + ' - ' + className) : cssName;
+ }
+ this.parsedClasses[nodeName][className] = cssName;
+ }
+ }
+ }
+ }
+ }
+ },
+ /*
+ * This function filters the class selectors allowed for each nodeName
+ *
+ * @return void
+ */
+ filterAllowedClasses: function() {
+ Ext.iterate(this.tags, function (nodeName) {
+ var allowedClasses = {};
+ // Get classes allowed for all tags
+ if (nodeName !== 'all' && Ext.isDefined(this.parsedClasses['all'])) {
+ if (this.tags && this.tags[nodeName] && this.tags[nodeName].allowedClasses) {
+ var allowed = this.tags[nodeName].allowedClasses;
+ Ext.iterate(this.parsedClasses['all'], function (cssClass, value) {
+ if (allowed.test(cssClass)) {
+ allowedClasses[cssClass] = value;
+ }
+ });
+ } else {
+ allowedClasses = this.parsedClasses['all'];
+ }
+ }
+ // Merge classes allowed for nodeName
+ if (Ext.isDefined(this.parsedClasses[nodeName])) {
+ if (this.tags && this.tags[nodeName] && this.tags[nodeName].allowedClasses) {
+ var allowed = this.tags[nodeName].allowedClasses;
+ Ext.iterate(this.parsedClasses[nodeName], function (cssClass, value) {
+ if (allowed.test(cssClass)) {
+ allowedClasses[cssClass] = value;
+ }
+ });
+ } else {
+ Ext.iterate(this.parsedClasses[nodeName], function (cssClass, value) {
+ allowedClasses[cssClass] = value;
+ });
+ }
+ }
+ this.parsedClasses[nodeName] = allowedClasses;
+ }, this);
+ // If showTagFreeClasses is set and there is no allowedClasses clause on a tag, merge classes allowed for all tags
+ if (this.showTagFreeClasses && Ext.isDefined(this.parsedClasses['all'])) {
+ Ext.iterate(this.parsedClasses, function (nodeName) {
+ if (nodeName !== 'all' && !this.tags[nodeName]) {
+ Ext.iterate(this.parsedClasses['all'], function (cssClass, value) {
+ this.parsedClasses[nodeName][cssClass] = value;
+ }, this);
+ }
+ }, this);
+ }
+ },
+ /*
+ * This function sorts the class selectors for each nodeName
+ *
+ * @return void
+ */
+ sort: function() {
+ Ext.iterate(this.parsedClasses, function (nodeName, value) {
+ var classes = [];
+ var sortedClasses= {};
+ // Collect keys
+ Ext.iterate(value, function (cssClass) {
+ classes.push(cssClass);
+ });
+ function compare(a, b) {
+ x = value[a];
+ y = value[b];
+ return ((x < y) ? -1 : ((x > y) ? 1 : 0));
+ }
+ // Sort keys by comparing texts
+ classes = classes.sort(compare);
+ for (var i = 0; i < classes.length; ++i) {
+ sortedClasses[classes[i]] = value[classes[i]];
+ }
+ this.parsedClasses[nodeName] = sortedClasses;
+ }, this);
+ }
+});
+/***************************************************
* TIPS ON FORM FIELDS AND MENU ITEMS
***************************************************/
/*
@@ -4156,7 +4625,7 @@
* @return string the localization of the label
*/
localize: function (label) {
- return this.I18N[label] || HTMLArea.I18N.dialogs[label] || HTMLArea.I18N.tooltips[label] || HTMLArea.I18N.msg[label];
+ return this.I18N[label] || HTMLArea.localize(label);
},
/**
* Load a Javascript file asynchronously
@@ -4167,22 +4636,8 @@
* @return boolean true on success of the request submission
*/
getJavascriptFile: function (url, callback) {
- var success = false;
this.appendToLog('getJavascriptFile', 'Requesting script ' + url);
- Ext.Ajax.request({
- method: 'GET',
- url: url,
- callback: callback,
- success: function (response) {
- success = true;
- },
- failure: function (response) {
- this.editor.inhibitKeyboardInput = false;
- this.appendToLog('getJavascriptFile', 'Unable to get ' + url + ' . Server reported ' + response.status);
- },
- scope: this
- });
- return success;
+ return this.editor.ajax.getJavascriptFile(url, callback, this);
},
/**
* Post data to the server
@@ -4193,39 +4648,10 @@
*
* @return boolean true on success
*/
- postData: function (url, data, callback) {
- var success = false;
- data.charset = this.editorConfiguration.typo3ContentCharset ? this.editorConfiguration.typo3ContentCharset : 'utf-8';
- var params = '';
- Ext.iterate(data, function (parameter, value) {
- params += (params.length ? '&' : '') + parameter + '=' + encodeURIComponent(value);
- });
- params += this.editorConfiguration.RTEtsConfigParams;
- this.appendToLog('postData', 'Posting to ' + url + '. Data: ' + params);
- Ext.Ajax.request({
- method: 'POST',
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
- },
- url: url,
- params: params,
- callback: Ext.isFunction(callback) ? callback: function (options, success, response) {
- if (success) {
- this.appendToLog('postData', 'Post request to ' + url + ' successful. Server response: ' + response.responseText);
- } else {
- this.appendToLog('postData', 'Post request to ' + url + ' failed. Server reported ' + response.status);
- }
- },
- success: function (response) {
- success = true;
- },
- failure: function (response) {
- this.appendToLog('postData', 'Unable to post ' + url + ' . Server reported ' + response.status);
- },
- scope: this
- });
- return success;
- },
+ postData: function (url, data, callback) {
+ this.appendToLog('postData', 'Posting to ' + url + '. Data: ' + params);
+ return this.editor.ajax.postData(url, data, callback, this);
+ },
/**
***********************************************
* THIS FUNCTION IS DEPRECATED AS OF TYPO3 4.4 *
@@ -4390,7 +4816,7 @@
* @return void
*/
appendToLog: function (functionName, text) {
- HTMLArea._appendToLog('[' + this.name + '::' + functionName + ']: ' + text);
+ this.editor.appendToLog(this.name, functionName, text);
},
/*
* Add a config element to config array if not empty
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/BlockElements/block-elements.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/BlockElements/block-elements.js (révision 9247)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/BlockElements/block-elements.js (copie de travail)
@@ -373,10 +373,10 @@
this.appendToLog("onButtonPress", e + "\n\nby execCommand(" + buttonId + ");");
}
} else if (this.isAllowedBlockElement("div")) {
- if (/^div$/i.test(parentElement.nodeName) && !HTMLArea._hasClass(parentElement, this.useClass[buttonId])) {
- HTMLArea._addClass(parentElement, this.useClass[buttonId]);
- } else if (!/^div$/i.test(parentElement.nodeName) && /^div$/i.test(parentElement.parentNode.nodeName) && !HTMLArea._hasClass(parentElement.parentNode, this.useClass[buttonId])) {
- HTMLArea._addClass(parentElement.parentNode, this.useClass[buttonId]);
+ if (/^div$/i.test(parentElement.nodeName) && !HTMLArea.DOM.hasClass(parentElement, this.useClass[buttonId])) {
+ HTMLArea.DOM.addClass(parentElement, this.useClass[buttonId]);
+ } else if (!/^div$/i.test(parentElement.nodeName) && /^div$/i.test(parentElement.parentNode.nodeName) && !HTMLArea.DOM.hasClass(parentElement.parentNode, this.useClass[buttonId])) {
+ HTMLArea.DOM.addClass(parentElement.parentNode, this.useClass[buttonId]);
} else {
var bookmark = this.editor.getBookmark(range);
var newBlock = this.wrapSelectionInBlockElement("div", this.useClass[buttonId], null, true);
@@ -387,7 +387,7 @@
}
break;
case "Outdent" :
- if (/^(ol|ul)$/i.test(parentElement.nodeName) && !HTMLArea._hasClass(parentElement, this.useClass.Indent)) {
+ if (/^(ol|ul)$/i.test(parentElement.nodeName) && !HTMLArea.DOM.hasClass(parentElement, this.useClass.Indent)) {
if (/^(li)$/i.test(parentElement.parentNode.nodeName)) {
if (Ext.isOpera) {
try {
@@ -433,7 +433,7 @@
}
} else if (this.isAllowedBlockElement("div")) {
for (var i = blockAncestors.length; --i >= 0;) {
- if (HTMLArea._hasClass(blockAncestors[i], this.useClass.Indent)) {
+ if (HTMLArea.DOM.hasClass(blockAncestors[i], this.useClass.Indent)) {
var bookmark = this.editor.getBookmark(range);
var newBlock = this.wrapSelectionInBlockElement("div", false, blockAncestors[i]);
// If not directly under the div, we need to backtrack
@@ -447,7 +447,7 @@
newBlock.appendChild(parent);
}
newBlock.className = blockAncestors[i].className;
- HTMLArea._removeClass(newBlock, this.useClass.Indent);
+ HTMLArea.DOM.removeClass(newBlock, this.useClass.Indent);
if (!newBlock.previousSibling) {
while (newBlock.hasChildNodes()) {
if (newBlock.firstChild.nodeType == 1) {
@@ -608,7 +608,7 @@
}
var blockElement = this.editor._doc.createElement(blockName);
if (useClass) {
- HTMLArea._addClass(blockElement, useClass);
+ HTMLArea.DOM.addClass(blockElement, useClass);
}
var contextElement = endAncestors[0];
if (i) {
@@ -664,13 +664,13 @@
if (HTMLArea.isBlockElement(block)) {
switch (buttonId) {
case "Indent" :
- if (!HTMLArea._hasClass(block, this.useClass[buttonId])) {
- HTMLArea._addClass(block, this.useClass[buttonId]);
+ if (!HTMLArea.DOM.hasClass(block, this.useClass[buttonId])) {
+ HTMLArea.DOM.addClass(block, this.useClass[buttonId]);
}
break;
case "Outdent" :
- if (HTMLArea._hasClass(block, this.useClass["Indent"])) {
- HTMLArea._removeClass(block, this.useClass["Indent"]);
+ if (HTMLArea.DOM.hasClass(block, this.useClass["Indent"])) {
+ HTMLArea.DOM.removeClass(block, this.useClass["Indent"]);
}
break;
case "JustifyLeft" :
@@ -683,7 +683,7 @@
if (this.standardBlockElements.test(buttonId.toLowerCase()) && buttonId.toLowerCase() == block.nodeName.toLowerCase()) {
this.cleanClasses(block);
if (className) {
- HTMLArea._addClass(block, className);
+ HTMLArea.DOM.addClass(block, className);
}
}
break;
@@ -702,10 +702,10 @@
toggleAlignmentClass : function(block, buttonId) {
for (var alignmentButtonId in this.useClass) {
if (this.useClass.hasOwnProperty(alignmentButtonId) && alignmentButtonId !== "Indent") {
- if (HTMLArea._hasClass(block, this.useClass[alignmentButtonId])) {
- HTMLArea._removeClass(block, this.useClass[alignmentButtonId]);
+ if (HTMLArea.DOM.hasClass(block, this.useClass[alignmentButtonId])) {
+ HTMLArea.DOM.removeClass(block, this.useClass[alignmentButtonId]);
} else if (alignmentButtonId === buttonId) {
- HTMLArea._addClass(block, this.useClass[alignmentButtonId]);
+ HTMLArea.DOM.addClass(block, this.useClass[alignmentButtonId]);
}
}
}
@@ -997,15 +997,15 @@
if (!HTMLArea.reservedClassNames.test(classNames[i])) {
if (this.tags && this.tags[nodeName] && this.tags[nodeName].allowedClasses) {
if (!this.tags[nodeName].allowedClasses.test(classNames[i])) {
- HTMLArea._removeClass(node, classNames[i]);
+ HTMLArea.DOM.removeClass(node, classNames[i]);
}
} else if (this.tags && this.tags.all && this.tags.all.allowedClasses) {
if (!this.tags.all.allowedClasses.test(classNames[i])) {
- HTMLArea._removeClass(node, classNames[i]);
+ HTMLArea.DOM.removeClass(node, classNames[i]);
}
}
if (this.formatBlockItems[nodeName] && this.formatBlockItems[nodeName].classList && this.formatBlockItems[nodeName].classList.test(classNames[i])) {
- HTMLArea._removeClass(node, classNames[i]);
+ HTMLArea.DOM.removeClass(node, classNames[i]);
}
}
}
@@ -1050,7 +1050,7 @@
commandState = true;
} else {
for (var j = blockAncestors.length; --j >= 0;) {
- if (HTMLArea._hasClass(blockAncestors[j], this.useClass.Indent) || /^(td|th)$/i.test(blockAncestors[j].nodeName)) {
+ if (HTMLArea.DOM.hasClass(blockAncestors[j], this.useClass.Indent) || /^(td|th)$/i.test(blockAncestors[j].nodeName)) {
commandState = true;
break;
}
@@ -1090,7 +1090,7 @@
button.setDisabled(false);
commandState = true;
for (var block = startAncestors[index]; block; block = block.nextSibling) {
- commandState = commandState && HTMLArea._hasClass(block, this.useClass[button.itemId]);
+ commandState = commandState && HTMLArea.DOM.hasClass(block, this.useClass[button.itemId]);
if (block == endAncestors[index]) {
break;
}
@@ -1159,7 +1159,7 @@
// Could be a custom item ...
index = store.findBy(function(record, id) {
var item = this.formatBlockItems[record.get('value')];
- return item && item.tagName == nodeName && item.addClass && HTMLArea._hasClass(deepestBlockAncestor, item.addClass);
+ return item && item.tagName == nodeName && item.addClass && HTMLArea.DOM.hasClass(deepestBlockAncestor, item.addClass);
}, this);
if (index == -1) {
// ... or a standard one
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/BlockStyle/block-style.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/BlockStyle/block-style.js (révision 9247)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/BlockStyle/block-style.js (copie de travail)
@@ -32,20 +32,14 @@
* TYPO3 SVN ID: $Id$
*/
HTMLArea.BlockStyle = HTMLArea.Plugin.extend({
-
constructor : function(editor, pluginName) {
this.base(editor, pluginName);
},
-
/*
* This function gets called by the class constructor
*/
- configurePlugin : function(editor) {
- this.cssLoaded = false;
- this.cssTimeout = null;
- this.cssParseCount = 0;
- this.cssArray = new Object();
-
+ configurePlugin: function (editor) {
+ this.cssArray = {};
this.classesUrl = this.editorConfiguration.classesUrl;
this.pageTSconfiguration = this.editorConfiguration.buttons.blockstyle;
this.tags = this.pageTSconfiguration.tags;
@@ -95,21 +89,19 @@
this.showTagFreeClasses = this.pageTSconfiguration.showTagFreeClasses || this.editorConfiguration.showTagFreeClasses;
this.prefixLabelWithClassName = this.pageTSconfiguration.prefixLabelWithClassName;
this.postfixLabelWithClassName = this.pageTSconfiguration.postfixLabelWithClassName;
-
/*
* Registering plugin "About" information
*/
var pluginInformation = {
- version : "1.4",
- developer : "Stanislas Rolland",
- developerUrl : "http://www.sjbr.ca/",
- copyrightOwner : "Stanislas Rolland",
- sponsor : this.localize("Technische Universitat Ilmenau"),
- sponsorUrl : "http://www.tu-ilmenau.de/",
- license : "GPL"
+ version : '2.0',
+ developer : 'Stanislas Rolland',
+ developerUrl : 'http://www.sjbr.ca/',
+ copyrightOwner : 'Stanislas Rolland',
+ sponsor : this.localize('Technische Universitat Ilmenau'),
+ sponsorUrl : 'http://www.tu-ilmenau.de/',
+ license : 'GPL'
};
this.registerPluginInformation(pluginInformation);
-
/*
* Registering the drop-down list
*/
@@ -139,11 +131,10 @@
this.registerDropDown(dropDownConfiguration);
return true;
},
-
/*
- * This function gets called when some block style was selected in the drop-down list
+ * This handler gets called when some block style was selected in the drop-down list
*/
- onChange : function (editor, combo, record, index) {
+ onChange: function (editor, combo, record, index) {
var className = combo.getValue();
this.editor.focus();
var blocks = this.getSelectedBlocks();
@@ -160,16 +151,15 @@
}
}
},
-
/*
* This function applies the class change to the node
*/
- applyClassChange : function (node, className) {
+ applyClassChange: function (node, className) {
if (className == "none") {
var classNames = node.className.trim().split(" ");
for (var i = classNames.length; --i >= 0;) {
if (!HTMLArea.reservedClassNames.test(classNames[i])) {
- HTMLArea._removeClass(node, classNames[i]);
+ HTMLArea.DOM.removeClass(node, classNames[i]);
if (node.nodeName.toLowerCase() === "table" && this.getPluginInstance('TableOperations')) {
this.getPluginInstance('TableOperations').removeAlternatingClasses(node, classNames[i]);
this.getPluginInstance('TableOperations').removeCountingClasses(node, classNames[i]);
@@ -181,25 +171,24 @@
var nodeName = node.nodeName.toLowerCase();
if (this.tags && this.tags[nodeName] && this.tags[nodeName].allowedClasses) {
if (this.tags[nodeName].allowedClasses.test(className)) {
- HTMLArea._addClass(node, className);
+ HTMLArea.DOM.addClass(node, className);
}
} else if (this.tags && this.tags.all && this.tags.all.allowedClasses) {
if (this.tags.all.allowedClasses.test(className)) {
- HTMLArea._addClass(node, className);
+ HTMLArea.DOM.addClass(node, className);
}
} else {
- HTMLArea._addClass(node, className);
+ HTMLArea.DOM.addClass(node, className);
}
if (nodeName === "table" && this.getPluginInstance('TableOperations')) {
this.getPluginInstance('TableOperations').reStyleTable(node);
}
}
},
-
/*
* This function gets the list of selected blocks
*/
- getSelectedBlocks : function() {
+ getSelectedBlocks: function () {
var block, range, i = 0, blocks = [];
var statusBarSelection = this.editor.statusBar ? this.editor.statusBar.getSelection() : null;
if (Ext.isGecko) {
@@ -218,67 +207,54 @@
return blocks;
},
/*
- * This function gets called when the editor is generated
+ * This handler gets called when the editor is generated
*/
- onGenerate: function() {
+ onGenerate: function () {
// Monitor editor changing mode
- this.editor.iframe.mon(this.editor, 'modeChange', this.onModeChange, this);
- if (!Ext.isIE) {
- this.generate(this.editor, 'BlockStyle');
- }
+ this.editor.iframe.mon(this.editor, 'HTMLAreaEventModeChange', this.onModeChange, this);
+ // Create CSS Parser object
+ this.blockStyles = new HTMLArea.CSS.Parser({
+ prefixLabelWithClassName: this.prefixLabelWithClassName,
+ postfixLabelWithClassName: this.postfixLabelWithClassName,
+ showTagFreeClasses: this.showTagFreeClasses,
+ tags: this.tags,
+ editor: this.editor
+ });
+ // Monitor css parsing being completed
+ this.editor.iframe.mon(this.blockStyles, 'HTMLAreaEventCssParsingComplete', this.onCssParsingComplete, this);
+ this.blockStyles.initiateParsing();
},
/*
- * This function gets called when the toolbar is being updated
+ * This handler gets called when parsing of css classes is completed
*/
- onUpdateToolbar: function (button, mode, selectionEmpty, ancestors) {
- if (mode === 'wysiwyg') {
- this.generate(this.editor, button.itemId);
+ onCssParsingComplete: function () {
+ if (this.blockStyles.isReady) {
+ this.cssArray = this.blockStyles.getClasses();
}
+ if (this.getEditorMode() === 'wysiwyg' && this.editor.isEditable()) {
+ this.updateValue('BlockStyle');
+ }
},
/*
- * This function gets called when the editor has changed its mode to "wysiwyg"
+ * This handler gets called when the toolbar is being updated
*/
- onModeChange: function(mode) {
- if (this.getEditorMode() === "wysiwyg") {
- this.generate(this.editor, "BlockStyle");
+ onUpdateToolbar: function (button, mode, selectionEmpty, ancestors) {
+ if (mode === 'wysiwyg' && this.editor.isEditable()) {
+ this.updateValue(button.itemId);
}
},
/*
- * This function gets called on plugin generation, on toolbar update and on change mode
- * Re-initiate the parsing of the style sheets, if not yet completed, and refresh our toolbar components
+ * This handler gets called when the editor has changed its mode to "wysiwyg"
*/
- generate: function(editor, dropDownId) {
- if (this.cssLoaded && this.getEditorMode() === 'wysiwyg' && this.editor.isEditable()) {
- this.updateValue(dropDownId);
- } else {
- if (this.cssTimeout) {
- window.clearTimeout(this.cssTimeout);
- this.cssTimeout = null;
- }
- if (this.classesUrl && (typeof(HTMLArea.classesLabels) === 'undefined')) {
- this.getJavascriptFile(this.classesUrl, function (options, success, response) {
- if (success) {
- try {
- if (typeof(HTMLArea.classesLabels) === 'undefined') {
- eval(response.responseText);
- this.appendToLog('generate', 'Javascript file successfully evaluated: ' + this.classesUrl);
- }
- } catch(e) {
- this.appendToLog('generate', 'Error evaluating contents of Javascript file: ' + this.classesUrl);
- }
- }
- this.buildCssArray(this.editor, dropDownId);
- });
- } else {
- this.buildCssArray(this.editor, dropDownId);
- }
+ onModeChange: function(mode) {
+ if (mode === 'wysiwyg' && this.editor.isEditable()) {
+ this.updateValue('BlockStyle');
}
},
-
/*
* This function updates the current value of the dropdown list
*/
- updateValue : function(dropDownId) {
+ updateValue: function(dropDownId) {
var dropDown = this.getButton(dropDownId);
if (dropDown) {
var classNames = new Array();
@@ -290,7 +266,7 @@
}
if (parent) {
tagName = parent.nodeName.toLowerCase();
- classNames = this.getClassNames(parent);
+ classNames = HTMLArea.DOM.getClassNames(parent);
}
if (tagName && tagName !== "body"){
this.buildDropDownOptions(dropDown, tagName);
@@ -301,34 +277,10 @@
}
}
},
-
/*
- * This function returns an array containing the class names assigned to the node
- */
- getClassNames : function (node) {
- var classNames = new Array();
- if (node) {
- if (node.className && /\S/.test(node.className)) {
- classNames = node.className.trim().split(" ");
- }
- if (HTMLArea.reservedClassNames.test(node.className)) {
- var cleanClassNames = new Array();
- var j = -1;
- for (var i = 0; i < classNames.length; ++i) {
- if (!HTMLArea.reservedClassNames.test(classNames[i])) {
- cleanClassNames[++j] = classNames[i];
- }
- }
- return cleanClassNames;
- }
- }
- return classNames;
- },
-
- /*
* This function reinitializes the options of the dropdown
*/
- initializeDropDown : function (dropDown) {
+ initializeDropDown: function (dropDown) {
var store = dropDown.getStore();
store.removeAll(false);
store.insert(0, new store.recordType({
@@ -337,94 +289,40 @@
}));
dropDown.setValue('none');
},
-
/*
* This function builds the options to be displayed in the dropDown box
*/
- buildDropDownOptions : function (dropDown, tagName) {
+ buildDropDownOptions: function (dropDown, nodeName) {
var store = dropDown.getStore();
- var cssArray = new Array();
this.initializeDropDown(dropDown);
- // Get classes allowed for all tags
- if (typeof(this.cssArray.all) !== "undefined") {
- var cssArrayAll = this.cssArray.all;
- if (this.tags && this.tags[tagName] && this.tags[tagName].allowedClasses) {
- var allowedClasses = this.tags[tagName].allowedClasses;
- for (var cssClass in cssArrayAll) {
- if (cssArrayAll.hasOwnProperty(cssClass) && allowedClasses.test(cssClass)) {
- cssArray[cssClass] = cssArrayAll[cssClass];
- }
- }
- } else {
- for (var cssClass in cssArrayAll) {
- if (cssArrayAll.hasOwnProperty(cssClass)) {
- cssArray[cssClass] = cssArrayAll[cssClass];
- }
- }
+ if (this.blockStyles.isReady) {
+ var allowedClasses = {};
+ if (Ext.isDefined(this.cssArray[nodeName])) {
+ allowedClasses = this.cssArray[nodeName];
+ } else if (this.showTagFreeClasses && Ext.isDefined(this.cssArray['all'])) {
+ allowedClasses = this.cssArray['all'];
}
- }
- // Merge classes allowed for tagName and sort the array
- if (typeof(this.cssArray[tagName]) !== "undefined") {
- var cssArrayTagName = this.cssArray[tagName];
- if (this.tags && this.tags[tagName] && this.tags[tagName].allowedClasses) {
- var allowedClasses = this.tags[tagName].allowedClasses;
- for (var cssClass in cssArrayTagName) {
- if (cssArrayTagName.hasOwnProperty(cssClass) && allowedClasses.test(cssClass)) {
- cssArray[cssClass] = cssArrayTagName[cssClass];
+ Ext.iterate(allowedClasses, function (cssClass, value) {
+ var style = null;
+ if (!this.editor.config.disablePCexamples) {
+ if (HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) {
+ style = HTMLArea.classesValues[cssClass];
+ } else if (/-[0-9]+$/.test(cssClass) && HTMLArea.classesValues[RegExp.leftContext + '-']) {
+ style = HTMLArea.classesValues[RegExp.leftContext + '-'];
}
}
- } else {
- for (var cssClass in cssArrayTagName) {
- if (cssArrayTagName.hasOwnProperty(cssClass)) {
- cssArray[cssClass] = cssArrayTagName[cssClass];
- }
- }
- }
- var sortedCssArray = new Object();
- var cssArrayKeys = new Array();
- for (var cssClass in cssArray) {
- if (cssArray.hasOwnProperty(cssClass)) {
- cssArrayKeys.push(cssClass);
- }
- }
- function compare(a, b) {
- x = cssArray[a];
- y = cssArray[b];
- return ((x < y) ? -1 : ((x > y) ? 1 : 0));
- }
- cssArrayKeys = cssArrayKeys.sort(compare);
- for (var i = 0; i < cssArrayKeys.length; ++i) {
- sortedCssArray[cssArrayKeys[i]] = cssArray[cssArrayKeys[i]];
- }
- cssArray = sortedCssArray;
+ store.add(new store.recordType({
+ text: value,
+ value: cssClass,
+ style: style
+ }));
+ }, this);
}
- for (var cssClass in cssArray) {
- if (cssArray.hasOwnProperty(cssClass) && cssArray[cssClass]) {
- if (cssClass == 'none') {
- store.getAt(0).set('text', cssArray[cssClass]);
- } else {
- var style = null;
- if (!this.editor.config.disablePCexamples) {
- if (HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) {
- style = HTMLArea.classesValues[cssClass];
- } else if (/-[0-9]+$/.test(cssClass) && HTMLArea.classesValues[RegExp.leftContext + '-']) {
- style = HTMLArea.classesValues[RegExp.leftContext + '-'];
- }
- }
- store.add(new store.recordType({
- text: cssArray[cssClass],
- value: cssClass,
- style: style
- }));
- }
- }
- }
},
-
/*
* This function sets the selected option of the dropDown box
*/
- setSelectedOption : function (dropDown, classNames, noUnknown, defaultClass) {
+ setSelectedOption: function (dropDown, classNames, noUnknown, defaultClass) {
var store = dropDown.getStore();
dropDown.setValue('none');
if (classNames.length) {
@@ -454,173 +352,5 @@
});
}
dropDown.setDisabled(!(store.getCount()>1));
- },
-
- /*
- * This function builds the main array of class selectors
- */
- buildCssArray : function(editor, dropDownId) {
- this.cssArray = this.parseStyleSheet();
- if (!this.cssLoaded && (this.cssParseCount < 17)) {
- this.cssTimeout = this.buildCssArray.defer(200, this, [editor, dropDownId]);
- this.cssParseCount++;
- } else {
- this.cssTimeout = null;
- this.cssLoaded = true;
- this.cssArray = this.sortCssArray(this.cssArray);
- this.updateValue(dropDownId);
- }
- },
-
- /*
- * This function parses the stylesheets
- */
- parseStyleSheet : function() {
- var iframe = this.editor._iframe.contentWindow ? this.editor._iframe.contentWindow.document : this.editor._iframe.contentDocument;
- var newCssArray = new Object();
- this.cssLoaded = true;
- for (var i = 0; i < iframe.styleSheets.length; i++) {
- if (!Ext.isIE) {
- try {
- newCssArray = this.parseCssRule(iframe.styleSheets[i].cssRules, newCssArray);
- } catch(e) {
- this.cssLoaded = false;
- }
- } else {
- try{
- // @import StyleSheets (IE)
- if (iframe.styleSheets[i].imports) {
- newCssArray = this.parseCssIEImport(iframe.styleSheets[i].imports, newCssArray);
- }
- if (iframe.styleSheets[i].rules) {
- newCssArray = this.parseCssRule(iframe.styleSheets[i].rules, newCssArray);
- }
- } catch(e) {
- this.cssLoaded = false;
- }
- }
- }
- return newCssArray;
- },
-
- /*
- * This function parses IE import rules
- */
- parseCssIEImport : function(cssIEImport, cssArray) {
- var newCssArray = new Object();
- newCssArray = cssArray;
- for (var i=0; i < cssIEImport.length; i++) {
- if (cssIEImport[i].imports) {
- newCssArray = this.parseCssIEImport(cssIEImport[i].imports, newCssArray);
- }
- if (cssIEImport[i].rules) {
- newCssArray = this.parseCssRule(cssIEImport[i].rules, newCssArray);
- }
- }
- return newCssArray;
- },
-
- /*
- * This function parses gecko css rules
- */
- parseCssRule : function(cssRules, cssArray) {
- var newCssArray = new Object();
- newCssArray = cssArray;
- for (var rule = 0; rule < cssRules.length; rule++) {
- // StyleRule
- if (cssRules[rule].selectorText) {
- newCssArray = this.parseSelectorText(cssRules[rule].selectorText, newCssArray);
- } else {
- // ImportRule (Mozilla)
- if (cssRules[rule].styleSheet) {
- newCssArray = this.parseCssRule(cssRules[rule].styleSheet.cssRules, newCssArray);
- }
- // MediaRule (Mozilla)
- if (cssRules[rule].cssRules) {
- newCssArray = this.parseCssRule(cssRules[rule].cssRules, newCssArray);
- }
- }
- }
- return newCssArray;
- },
-
- /*
- * This function parses each selector rule
- */
- parseSelectorText : function(selectorText, cssArray) {
- var cssElements = new Array();
- var cssElement = new Array();
- var tagName, className;
- var newCssArray = new Object();
- newCssArray = cssArray;
- if (selectorText.search(/:+/) == -1) {
- // split equal Styles (Mozilla-specific) e.q. head, body {border:0px}
- // for ie not relevant. returns allways one element
- cssElements = selectorText.split(",");
- for (var k = 0; k < cssElements.length; k++) {
- // Match ALL classes (.) in selector rule
- var s = cssElements[k],
- pattern = /(\S*)\.(\S+)/,
- index;
- while ((index = s.search(pattern)) > -1) {
- var match = pattern.exec(s.substring(index));
- s = s.substring(index+match[0].length);
-
- tagName = (match[1] && (match[1] != '*')) ? match[1].toLowerCase().trim() : "all";
- className = match[2];
-
- if (className && !HTMLArea.reservedClassNames.test(className)) {
- if (((tagName != "all") && (!this.tags || !this.tags[tagName]))
- || ((tagName == "all") && (!this.tags || !this.tags[tagName]) && this.showTagFreeClasses)
- || (this.tags && this.tags[tagName] && this.tags[tagName].allowedClasses && this.tags[tagName].allowedClasses.test(className))) {
- if (!newCssArray[tagName]) {
- newCssArray[tagName] = new Object();
- }
- if (className) {
- cssName = className;
- if (HTMLArea.classesLabels && HTMLArea.classesLabels[className]) {
- cssName = this.prefixLabelWithClassName ? (className + " - " + HTMLArea.classesLabels[className]) : HTMLArea.classesLabels[className];
- cssName = this.postfixLabelWithClassName ? (cssName + " - " + className) : cssName;
- }
- } else {
- className = "none";
- cssName = this.localize("Element style");
- }
- newCssArray[tagName][className] = cssName;
- }
- }
- }
- }
- }
- return newCssArray;
- },
-
- /*
- * This function sorts the main array of class selectors
- */
- sortCssArray : function(cssArray) {
- var newCssArray = new Object();
- for (var tagName in cssArray) {
- if (cssArray.hasOwnProperty(tagName)) {
- newCssArray[tagName] = new Object();
- var tagArrayKeys = new Array();
- for (var cssClass in cssArray[tagName]) {
- if (cssArray[tagName].hasOwnProperty(cssClass)) {
- tagArrayKeys.push(cssClass);
- }
- }
- function compare(a, b) {
- x = cssArray[tagName][a];
- y = cssArray[tagName][b];
- return ((x < y) ? -1 : ((x > y) ? 1 : 0));
- }
- tagArrayKeys = tagArrayKeys.sort(compare);
- for (var i = 0; i < tagArrayKeys.length; ++i) {
- newCssArray[tagName][tagArrayKeys[i]] = cssArray[tagName][tagArrayKeys[i]];
- }
- }
- }
- return newCssArray;
}
});
-
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/InlineElements/inline-elements.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/InlineElements/inline-elements.js (révision 9247)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/InlineElements/inline-elements.js (copie de travail)
@@ -357,7 +357,7 @@
classNames = newElement.className.trim().split(" ");
for (var i = 0; i < classNames.length; ++i) {
if (!allowedClasses.test(classNames[i])) {
- HTMLArea._removeClass(newElement, classNames[i]);
+ HTMLArea.DOM.removeClass(newElement, classNames[i]);
}
}
}
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/Language/language.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/Language/language.js (révision 9247)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/Language/language.js (copie de travail)
@@ -216,10 +216,10 @@
*/
toggleLanguageMarks : function (forceLanguageMarks) {
var body = this.editor._doc.body;
- if (!HTMLArea._hasClass(body, 'htmlarea-show-language-marks')) {
- HTMLArea._addClass(body,'htmlarea-show-language-marks');
+ if (!HTMLArea.DOM.hasClass(body, 'htmlarea-show-language-marks')) {
+ HTMLArea.DOM.addClass(body,'htmlarea-show-language-marks');
} else if (!forceLanguageMarks) {
- HTMLArea._removeClass(body,'htmlarea-show-language-marks');
+ HTMLArea.DOM.removeClass(body,'htmlarea-show-language-marks');
}
},
@@ -408,7 +408,7 @@
}
break;
case 'ShowLanguageMarks':
- button.setInactive(!HTMLArea._hasClass(this.editor._doc.body, 'htmlarea-show-language-marks'));
+ button.setInactive(!HTMLArea.DOM.hasClass(this.editor._doc.body, 'htmlarea-show-language-marks'));
break;
case 'Language':
// Updating the language drop-down
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-checker.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-checker.js (révision 9247)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-checker.js (copie de travail)
@@ -485,13 +485,13 @@
element.onclick = null;
element.onmouseover = null;
element.onmouseout = null;
- if (!leaveFixed || !HTMLArea._hasClass(element, 'htmlarea-spellcheck-fixed')) {
+ if (!leaveFixed || !HTMLArea.DOM.hasClass(element, 'htmlarea-spellcheck-fixed')) {
element.parentNode.insertBefore(element.firstChild, element);
element.parentNode.removeChild(element);
} else {
- HTMLArea._removeClass(element, 'htmlarea-spellcheck-error');
- HTMLArea._removeClass(element, 'htmlarea-spellcheck-same');
- HTMLArea._removeClass(element, 'htmlarea-spellcheck-current');
+ HTMLArea.DOM.removeClass(element, 'htmlarea-spellcheck-error');
+ HTMLArea.DOM.removeClass(element, 'htmlarea-spellcheck-same');
+ HTMLArea.DOM.removeClass(element, 'htmlarea-spellcheck-current');
}
}, this);
// Cleanup event handlers on links
@@ -521,11 +521,11 @@
var id = 0;
var self = this;
Ext.each(contentWindow.document.getElementsByTagName('span'), function (span) {
- if (HTMLArea._hasClass(span, 'htmlarea-spellcheck-error')) {
+ if (HTMLArea.DOM.hasClass(span, 'htmlarea-spellcheck-error')) {
this.misspelledWords.push(span);
span.onclick = function (event) { self.setCurrentWord(this, false); };
- span.onmouseover = function (event) { HTMLArea._addClass(this, 'htmlarea-spellcheck-hover'); };
- span.onmouseout = function (event) { HTMLArea._removeClass(this, 'htmlarea-spellcheck-hover'); };
+ span.onmouseover = function (event) { HTMLArea.DOM.addClass(this, 'htmlarea-spellcheck-hover'); };
+ span.onmouseout = function (event) { HTMLArea.DOM.removeClass(this, 'htmlarea-spellcheck-hover'); };
span.htmlareaId = id++;
span.htmlareaOriginalWord = span.firstChild.data;
span.htmlareaFixed = false;
@@ -533,7 +533,7 @@
this.allWords[span.htmlareaOriginalWord] = [];
}
this.allWords[span.htmlareaOriginalWord].push(span);
- } else if (HTMLArea._hasClass(span, 'htmlarea-spellcheck-fixed')) {
+ } else if (HTMLArea.DOM.hasClass(span, 'htmlarea-spellcheck-fixed')) {
this.correctedWords.push(span);
}
}, this);
@@ -624,18 +624,18 @@
}
// De-highlight all occurrences of current word
if (this.currentElement) {
- HTMLArea._removeClass(this.currentElement, 'htmlarea-spellcheck-current');
+ HTMLArea.DOM.removeClass(this.currentElement, 'htmlarea-spellcheck-current');
Ext.each(this.allWords[this.currentElement.htmlareaOriginalWord], function (word) {
- HTMLArea._removeClass(word, 'htmlarea-spellcheck-same');
+ HTMLArea.DOM.removeClass(word, 'htmlarea-spellcheck-same');
});
}
// Highlight all occurrences of new current word
this.currentElement = element;
- HTMLArea._addClass(this.currentElement, 'htmlarea-spellcheck-current');
+ HTMLArea.DOM.addClass(this.currentElement, 'htmlarea-spellcheck-current');
var occurrences = this.allWords[this.currentElement.htmlareaOriginalWord];
Ext.each(occurrences, function (word) {
if (word != this.currentElement) {
- HTMLArea._addClass(word, 'htmlarea-spellcheck-same');
+ HTMLArea.DOM.addClass(word, 'htmlarea-spellcheck-same');
}
}, this);
this.dialog.find('itemId', 'replaceAll')[0].setDisabled(occurrences.length <= 1);
@@ -685,13 +685,13 @@
* Handler invoked when the mouse moves over a misspelled word
*/
onWordMouseOver: function (event, element) {
- HTMLArea._addClass(element, 'htmlarea-spellcheck-hover');
+ HTMLArea.DOM.addClass(element, 'htmlarea-spellcheck-hover');
},
/*
* Handler invoked when the mouse moves out of a misspelled word
*/
onWordMouseOut: function (event, element) {
- HTMLArea._removeClass(element, 'htmlarea-spellcheck-hover');
+ HTMLArea.DOM.removeClass(element, 'htmlarea-spellcheck-hover');
},
/*
* Handler invoked when a suggestion is selected
@@ -711,17 +711,17 @@
onRevertClick: function () {
this.dialog.find('itemId', 'replacement')[0].setValue(this.currentElement.htmlareaOriginalWord);
this.replaceWord(this.currentElement);
- HTMLArea._removeClass(this.currentElement, 'htmlarea-spellcheck-fixed');
- HTMLArea._addClass(this.currentElement, 'htmlarea-spellcheck-error');
- HTMLArea._addClass(this.currentElement, 'htmlarea-spellcheck-current');
+ HTMLArea.DOM.removeClass(this.currentElement, 'htmlarea-spellcheck-fixed');
+ HTMLArea.DOM.addClass(this.currentElement, 'htmlarea-spellcheck-error');
+ HTMLArea.DOM.addClass(this.currentElement, 'htmlarea-spellcheck-current');
return false;
},
/*
* Replace the word contained in the element
*/
replaceWord: function (element) {
- HTMLArea._removeClass(element, 'htmlarea-spellcheck-hover');
- HTMLArea._addClass(element, 'htmlarea-spellcheck-fixed');
+ HTMLArea.DOM.removeClass(element, 'htmlarea-spellcheck-hover');
+ HTMLArea.DOM.addClass(element, 'htmlarea-spellcheck-fixed');
element.htmlareaFixed = true;
var replacement = this.dialog.find('itemId', 'replacement')[0].getValue();
if (element.innerHTML != replacement) {
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/TableOperations/table-operations.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/TableOperations/table-operations.js (révision 9247)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/TableOperations/table-operations.js (copie de travail)
@@ -264,11 +264,8 @@
}
break;
}
- if (this.removedFieldsets.indexOf('style') == -1 && this.getButton('BlockStyle')) {
- var blockStyle = this.getPluginInstance('BlockStyle');
- if (blockStyle && blockStyle.cssLoaded) {
- this.addConfigElement(this.buildStylingFieldsetConfig(element, buttonId), generalTabItems);
- }
+ if (this.removedFieldsets.indexOf('style') == -1 && this.getPluginInstance('BlockStyle')) {
+ this.addConfigElement(this.buildStylingFieldsetConfig(element, buttonId), generalTabItems);
}
if (!Ext.isEmpty(generalTabItems)) {
tabItems.push({
@@ -525,16 +522,16 @@
case "f_st_float":
switch (val) {
case "not set":
- HTMLArea._removeClass(table, this.floatRight);
- HTMLArea._removeClass(table, this.floatLeft);
+ HTMLArea.DOM.removeClass(table, this.floatRight);
+ HTMLArea.DOM.removeClass(table, this.floatLeft);
break;
case "right":
- HTMLArea._removeClass(table, this.floatLeft);
- HTMLArea._addClass(table, this.floatRight);
+ HTMLArea.DOM.removeClass(table, this.floatLeft);
+ HTMLArea.DOM.addClass(table, this.floatRight);
break;
case "left":
- HTMLArea._removeClass(table, this.floatRight);
- HTMLArea._addClass(table, this.floatLeft);
+ HTMLArea.DOM.removeClass(table, this.floatRight);
+ HTMLArea.DOM.addClass(table, this.floatLeft);
break;
}
break;
@@ -685,7 +682,7 @@
*/
onUpdateToolbar: function (button, mode, selectionEmpty, ancestors) {
if (mode === 'wysiwyg' && this.editor.isEditable() && button.itemId === 'TO-toggle-borders') {
- button.setInactive(!HTMLArea._hasClass(this.editor._doc.body, 'htmlarea-showtableborders'));
+ button.setInactive(!HTMLArea.DOM.hasClass(this.editor._doc.body, 'htmlarea-showtableborders'));
}
},
/*
@@ -1182,10 +1179,10 @@
*/
toggleBorders : function (forceBorders) {
var body = this.editor._doc.body;
- if (!HTMLArea._hasClass(body, 'htmlarea-showtableborders')) {
- HTMLArea._addClass(body,'htmlarea-showtableborders');
+ if (!HTMLArea.DOM.hasClass(body, 'htmlarea-showtableborders')) {
+ HTMLArea.DOM.addClass(body,'htmlarea-showtableborders');
} else if (!forceBorders) {
- HTMLArea._removeClass(body,'htmlarea-showtableborders');
+ HTMLArea.DOM.removeClass(body,'htmlarea-showtableborders');
}
},
/*
@@ -1299,20 +1296,20 @@
odd = oddClass[type];
even = evenClass[type];
if (remove) {
- HTMLArea._removeClass(row, odd);
- HTMLArea._removeClass(row, even);
+ HTMLArea.DOM.removeClass(row, odd);
+ HTMLArea.DOM.removeClass(row, even);
// Check if i is even, and apply classes for both possible results
} else if (odd && even) {
if ((i % 2) == 0) {
- if (HTMLArea._hasClass(row, even)) {
- HTMLArea._removeClass(row, even);
+ if (HTMLArea.DOM.hasClass(row, even)) {
+ HTMLArea.DOM.removeClass(row, even);
}
- HTMLArea._addClass(row, odd);
+ HTMLArea.DOM.addClass(row, odd);
} else {
- if (HTMLArea._hasClass(row, odd)) {
- HTMLArea._removeClass(row, odd);
+ if (HTMLArea.DOM.hasClass(row, odd)) {
+ HTMLArea.DOM.removeClass(row, odd);
}
- HTMLArea._addClass(row, even);
+ HTMLArea.DOM.addClass(row, even);
}
}
}
@@ -1342,20 +1339,20 @@
odd = oddClass[type];
even = evenClass[type];
if (remove) {
- if (odd) HTMLArea._removeClass(cell, odd);
- if (even) HTMLArea._removeClass(cell, even);
+ if (odd) HTMLArea.DOM.removeClass(cell, odd);
+ if (even) HTMLArea.DOM.removeClass(cell, even);
} else if (odd && even) {
// Check if j+startAt is even, and apply classes for both possible results
if ((j % 2) == 0) {
- if (HTMLArea._hasClass(cell, even)) {
- HTMLArea._removeClass(cell, even);
+ if (HTMLArea.DOM.hasClass(cell, even)) {
+ HTMLArea.DOM.removeClass(cell, even);
}
- HTMLArea._addClass(cell, odd);
+ HTMLArea.DOM.addClass(cell, odd);
} else{
- if (HTMLArea._hasClass(cell, odd)) {
- HTMLArea._removeClass(cell, odd);
+ if (HTMLArea.DOM.hasClass(cell, odd)) {
+ HTMLArea.DOM.removeClass(cell, odd);
}
- HTMLArea._addClass(cell, even);
+ HTMLArea.DOM.addClass(cell, even);
}
}
}
@@ -1422,23 +1419,23 @@
lastRowClassName = rowLastClass[type];
if (remove) {
if (baseClassName) {
- HTMLArea._removeClass(row, rowClassName);
+ HTMLArea.DOM.removeClass(row, rowClassName);
}
if (lastRowClassName && i == n-1) {
- HTMLArea._removeClass(row, lastRowClassName);
+ HTMLArea.DOM.removeClass(row, lastRowClassName);
}
} else {
if (baseClassName) {
- if (HTMLArea._hasClass(row, baseClassName, true)) {
- HTMLArea._removeClass(row, baseClassName, true);
+ if (HTMLArea.DOM.hasClass(row, baseClassName, true)) {
+ HTMLArea.DOM.removeClass(row, baseClassName, true);
}
- HTMLArea._addClass(row, rowClassName);
+ HTMLArea.DOM.addClass(row, rowClassName);
}
if (lastRowClassName) {
if (i == n-1) {
- HTMLArea._addClass(row, lastRowClassName);
- } else if (HTMLArea._hasClass(row, lastRowClassName)) {
- HTMLArea._removeClass(row, lastRowClassName);
+ HTMLArea.DOM.addClass(row, lastRowClassName);
+ } else if (HTMLArea.DOM.hasClass(row, lastRowClassName)) {
+ HTMLArea.DOM.removeClass(row, lastRowClassName);
}
}
}
@@ -1471,23 +1468,23 @@
lastColumnClassName = columnLastClass[type];
if (remove) {
if (baseClassName) {
- HTMLArea._removeClass(cell, columnClassName);
+ HTMLArea.DOM.removeClass(cell, columnClassName);
}
if (lastColumnClassName && j == n-1) {
- HTMLArea._removeClass(cell, lastColumnClassName);
+ HTMLArea.DOM.removeClass(cell, lastColumnClassName);
}
} else {
if (baseClassName) {
- if (HTMLArea._hasClass(cell, baseClassName, true)) {
- HTMLArea._removeClass(cell, baseClassName, true);
+ if (HTMLArea.DOM.hasClass(cell, baseClassName, true)) {
+ HTMLArea.DOM.removeClass(cell, baseClassName, true);
}
- HTMLArea._addClass(cell, columnClassName);
+ HTMLArea.DOM.addClass(cell, columnClassName);
}
if (lastColumnClassName) {
if (j == n-1) {
- HTMLArea._addClass(cell, lastColumnClassName);
- } else if (HTMLArea._hasClass(cell, lastColumnClassName)) {
- HTMLArea._removeClass(cell, lastColumnClassName);
+ HTMLArea.DOM.addClass(cell, lastColumnClassName);
+ } else if (HTMLArea.DOM.hasClass(cell, lastColumnClassName)) {
+ HTMLArea.DOM.removeClass(cell, lastColumnClassName);
}
}
}
@@ -1521,7 +1518,7 @@
} else {
var firstRow = thead.rows[0];
}
- HTMLArea._removeClass(firstRow, this.useHeaderClass);
+ HTMLArea.DOM.removeClass(firstRow, this.useHeaderClass);
} else {
if (thead) {
var rows = thead.rows;
@@ -1540,10 +1537,10 @@
}
if (headers == "both") {
var firstRow = tbody.rows[0];
- HTMLArea._addClass(firstRow, this.useHeaderClass);
+ HTMLArea.DOM.addClass(firstRow, this.useHeaderClass);
} else if (headers != "top") {
var firstRow = tbody.rows[0];
- HTMLArea._removeClass(firstRow, this.useHeaderClass);
+ HTMLArea.DOM.removeClass(firstRow, this.useHeaderClass);
this.remapRowCells(firstRow, "td");
}
if (headers == "top" || headers == "both") {
@@ -1613,7 +1610,7 @@
var classNames = newCell.className.trim().split(" ");
for (var i = classNames.length; --i >= 0;) {
if (!allowedClasses.test(classNames[i])) {
- HTMLArea._removeClass(newCell, classNames[i]);
+ HTMLArea.DOM.removeClass(newCell, classNames[i]);
}
}
}
@@ -1818,7 +1815,7 @@
if (thead.length && thead[0].rows.length) {
selected = 'top';
} else if (tbody.length && tbody[0].rows.length) {
- if (HTMLArea._hasClass(tbody[0].rows[0], this.useHeaderClass)) {
+ if (HTMLArea.DOM.hasClass(tbody[0].rows[0], this.useHeaderClass)) {
selected = 'both';
} else if (tbody[0].rows[0].cells.length && tbody[0].rows[0].cells[0].nodeName.toLowerCase() == 'th') {
selected = 'left';
@@ -1928,12 +1925,12 @@
*/
setStyleOptions: function (dropDown, element, nodeName, defaultClass) {
var blockStyle = this.getPluginInstance('BlockStyle');
- if (dropDown && blockStyle && blockStyle.cssLoaded) {
+ if (dropDown && blockStyle) {
if (defaultClass) {
var classNames = new Array();
classNames.push(defaultClass);
} else {
- var classNames = blockStyle.getClassNames(element);
+ var classNames = HTMLArea.DOM.getClassNames(element);
}
blockStyle.buildDropDownOptions(dropDown, nodeName);
blockStyle.setSelectedOption(dropDown, classNames, 'noUnknown', defaultClass);
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/TextStyle/text-style.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/TextStyle/text-style.js (révision 9247)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/TextStyle/text-style.js (copie de travail)
@@ -36,20 +36,14 @@
/*
* Let the base class do some initialization work
*/
- constructor : function(editor, pluginName) {
+ constructor: function (editor, pluginName) {
this.base(editor, pluginName);
},
-
/*
* This function gets called by the class constructor
*/
- configurePlugin : function (editor) {
-
- this.cssLoaded = false;
- this.cssTimeout = null;
- this.cssParseCount = 0;
- this.cssArray = new Object();
-
+ configurePlugin: function (editor) {
+ this.cssArray = {};
this.classesUrl = this.editorConfiguration.classesUrl;
this.pageTSconfiguration = this.editorConfiguration.buttons.textstyle;
this.tags = this.pageTSconfiguration.tags;
@@ -94,21 +88,19 @@
if (Ext.isIE) {
this.addAllowedAttribute("className");
}
-
/*
* Registering plugin "About" information
*/
var pluginInformation = {
- version : "1.1",
- developer : "Stanislas Rolland",
- developerUrl : "http://www.sjbr.ca/",
- copyrightOwner : "Stanislas Rolland",
- sponsor : this.localize("Technische Universitat Ilmenau"),
- sponsorUrl : "http://www.tu-ilmenau.de/",
- license : "GPL"
+ version : '2.0',
+ developer : 'Stanislas Rolland',
+ developerUrl : 'http://www.sjbr.ca/',
+ copyrightOwner : 'Stanislas Rolland',
+ sponsor : this.localize('Technische Universitat Ilmenau'),
+ sponsorUrl : 'http://www.tu-ilmenau.de/',
+ license : 'GPL'
};
this.registerPluginInformation(pluginInformation);
-
/*
* Registering the dropdown list
*/
@@ -139,10 +131,9 @@
return true;
},
- isInlineElement : function (el) {
+ isInlineElement: function (el) {
return el && (el.nodeType === 1) && this.REInlineTags.test(el.nodeName.toLowerCase());
},
-
/*
* This function adds an attribute to the array of allowed attributes on inline elements
*
@@ -150,14 +141,13 @@
*
* @return void
*/
- addAllowedAttribute : function (attribute) {
+ addAllowedAttribute: function (attribute) {
this.allowedAttributes.push(attribute);
},
-
/*
* This function gets called when some style in the drop-down list applies it to the highlighted textt
*/
- onChange : function (editor, combo, record, index) {
+ onChange: function (editor, combo, record, index) {
var className = combo.getValue();
var classNames = null;
var fullNodeSelected = false;
@@ -196,7 +186,7 @@
if (className !== "none") {
// Add span element with class attribute
var newElement = editor._doc.createElement("span");
- HTMLArea._addClass(newElement, className);
+ HTMLArea.DOM.addClass(newElement, className);
editor.wrapWithInlineElement(newElement, selection, range);
if (!Ext.isIE) {
range.detach();
@@ -207,10 +197,10 @@
if (parent && !HTMLArea.isBlockElement(parent)) {
if (className === "none" && parent.className && /\S/.test(parent.className)) {
classNames = parent.className.trim().split(" ");
- HTMLArea._removeClass(parent, classNames[classNames.length-1]);
+ HTMLArea.DOM.removeClass(parent, classNames[classNames.length-1]);
}
if (className !== "none") {
- HTMLArea._addClass(parent, className);
+ HTMLArea.DOM.addClass(parent, className);
}
// Remove the span tag if it has no more attribute
if ((parent.nodeName.toLowerCase() === "span") && !HTMLArea.hasAllowedAttributes(parent, this.allowedAttributes)) {
@@ -219,211 +209,56 @@
}
}
},
-
/*
* This function gets called when the plugin is generated
* Get the classes configuration and initiate the parsing of the style sheets
*/
- onGenerate: function() {
+ onGenerate: function () {
// Monitor editor changing mode
- this.editor.iframe.mon(this.editor, 'modeChange', this.onModeChange, this);
- this.generate(this.editor, "TextStyle");
+ this.editor.iframe.mon(this.editor, 'HTMLAreaEventModeChange', this.onModeChange, this);
+ // Create CSS Parser object
+ this.textStyles = new HTMLArea.CSS.Parser({
+ prefixLabelWithClassName: this.prefixLabelWithClassName,
+ postfixLabelWithClassName: this.postfixLabelWithClassName,
+ showTagFreeClasses: this.showTagFreeClasses,
+ tags: this.tags,
+ editor: this.editor
+ });
+ // Monitor css parsing being completed
+ this.editor.iframe.mon(this.textStyles, 'HTMLAreaEventCssParsingComplete', this.onCssParsingComplete, this);
+ this.textStyles.initiateParsing();
},
-
/*
- * This function gets called on plugin generation, on toolbar update and on change mode
- * Re-initiate the parsing of the style sheets, if not yet completed, and refresh our toolbar components
+ * This handler gets called when parsing of css classes is completed
*/
- generate: function (editor, dropDownId) {
- if (this.cssLoaded) {
- this.updateToolbar(dropDownId);
- } else {
- if (this.cssTimeout) {
- window.clearTimeout(this.cssTimeout);
- this.cssTimeout = null;
- }
- if (this.classesUrl && (typeof(HTMLArea.classesLabels) === 'undefined')) {
- this.getJavascriptFile(this.classesUrl, function (options, success, response) {
- if (success) {
- try {
- if (typeof(HTMLArea.classesLabels) === 'undefined') {
- eval(response.responseText);
- this.appendToLog('generate', 'Javascript file successfully evaluated: ' + this.classesUrl);
- }
- } catch(e) {
- this.appendToLog('generate', 'Error evaluating contents of Javascript file: ' + this.classesUrl);
- }
- }
- this.buildCssArray(this.editor, dropDownId);
- });
- } else {
- this.buildCssArray(this.editor, dropDownId);
- }
+ onCssParsingComplete: function () {
+ if (this.textStyles.isReady) {
+ this.cssArray = this.textStyles.getClasses();
}
- },
-
- buildCssArray : function(editor, dropDownId) {
- this.cssArray = this.parseStyleSheet();
- if (!this.cssLoaded && (this.cssParseCount < 17)) {
- this.cssTimeout = this.buildCssArray.defer(200, this, [editor, dropDownId]);
- this.cssParseCount++;
- } else {
- this.cssTimeout = null;
- this.cssLoaded = true;
- this.cssArray = this.sortCssArray(this.cssArray);
- this.updateToolbar(dropDownId);
+ if (this.getEditorMode() === 'wysiwyg' && this.editor.isEditable()) {
+ this.updateToolbar('TextStyle');
}
},
-
- parseStyleSheet : function() {
- var iframe = this.editor._iframe.contentWindow ? this.editor._iframe.contentWindow.document : this.editor._iframe.contentDocument;
- var newCssArray = new Object();
- this.cssLoaded = true;
- for (var i = 0; i < iframe.styleSheets.length; i++) {
- if (!Ext.isIE) {
- try {
- newCssArray = this.parseCssRule(iframe.styleSheets[i].cssRules, newCssArray);
- } catch(e) {
- this.cssLoaded = false;
- }
- } else {
- try{
- // @import StyleSheets (IE)
- if (iframe.styleSheets[i].imports) {
- newCssArray = this.parseCssIEImport(iframe.styleSheets[i].imports, newCssArray);
- }
- if (iframe.styleSheets[i].rules) {
- newCssArray = this.parseCssRule(iframe.styleSheets[i].rules, newCssArray);
- }
- } catch(e) {
- this.cssLoaded = false;
- }
- }
+ /*
+ * This handler gets called when the toolbar is being updated
+ */
+ onUpdateToolbar: function (button, mode, selectionEmpty, ancestors) {
+ if (mode === 'wysiwyg' && this.editor.isEditable()) {
+ this.updateToolbar(button.itemId);
}
- return newCssArray;
},
-
- parseCssIEImport : function(cssIEImport, cssArray) {
- var newCssArray = new Object();
- newCssArray = cssArray;
- for (var i=0; i < cssIEImport.length; i++) {
- if (cssIEImport[i].imports) {
- newCssArray = this.parseCssIEImport(cssIEImport[i].imports, newCssArray);
- }
- if (cssIEImport[i].rules) {
- newCssArray = this.parseCssRule(cssIEImport[i].rules, newCssArray);
- }
- }
- return newCssArray;
- },
-
- parseCssRule : function(cssRules, cssArray) {
- var newCssArray = new Object();
- newCssArray = cssArray;
- for (var rule = 0; rule < cssRules.length; rule++) {
- // StyleRule
- if (cssRules[rule].selectorText) {
- newCssArray = this.parseSelectorText(cssRules[rule].selectorText, newCssArray);
- } else {
- // ImportRule (Mozilla)
- if (cssRules[rule].styleSheet) {
- newCssArray = this.parseCssRule(cssRules[rule].styleSheet.cssRules, newCssArray);
- }
- // MediaRule (Mozilla)
- if (cssRules[rule].cssRules) {
- newCssArray = this.parseCssRule(cssRules[rule].cssRules, newCssArray);
- }
- }
- }
- return newCssArray;
- },
-
- parseSelectorText : function(selectorText, cssArray) {
- var cssElements = new Array();
- var cssElement = new Array();
- var tagName, className;
- var newCssArray = new Object();
- newCssArray = cssArray;
- if (selectorText.search(/:+/) == -1) {
- // split equal Styles (Mozilla-specific) e.q. head, body {border:0px}
- // for ie not relevant. returns allways one element
- cssElements = selectorText.split(",");
- for (var k = 0; k < cssElements.length; k++) {
- // Match ALL classes (.) in selector rule
- var s = cssElements[k],
- pattern = /(\S*)\.(\S+)/,
- index;
- while ((index = s.search(pattern)) > -1) {
- var match = pattern.exec(s.substring(index));
- s = s.substring(index+match[0].length);
-
- tagName = (match[1] && (match[1] != '*')) ? match[1].toLowerCase().trim() : "all";
- className = match[2];
-
- if (className && !HTMLArea.reservedClassNames.test(className)) {
- if (((tagName != "all") && (!this.tags || !this.tags[tagName]))
- || ((tagName == "all") && (!this.tags || !this.tags[tagName]) && this.showTagFreeClasses)
- || (this.tags && this.tags[tagName] && this.tags[tagName].allowedClasses && this.tags[tagName].allowedClasses.test(className))) {
- if (!newCssArray[tagName]) {
- newCssArray[tagName] = new Object();
- }
- if (className) {
- cssName = className;
- if (HTMLArea.classesLabels && HTMLArea.classesLabels[className]) {
- cssName = this.prefixLabelWithClassName ? (className + " - " + HTMLArea.classesLabels[className]) : HTMLArea.classesLabels[className];
- cssName = this.postfixLabelWithClassName ? (cssName + " - " + className) : cssName;
- }
- } else {
- className = 'none';
- cssName = this.localize("Element style");
- }
- newCssArray[tagName][className] = cssName;
- }
- }
- }
- }
- }
- return newCssArray;
- },
-
- sortCssArray : function(cssArray) {
- var newCssArray = new Object();
- for (var tagName in cssArray) {
- if (cssArray.hasOwnProperty(tagName)) {
- newCssArray[tagName] = new Object();
- var tagArrayKeys = new Array();
- for (var cssClass in cssArray[tagName]) {
- if (cssArray[tagName].hasOwnProperty(cssClass)) {
- tagArrayKeys.push(cssClass);
- }
- }
- function compare(a, b) {
- x = cssArray[tagName][a];
- y = cssArray[tagName][b];
- return ((x < y) ? -1 : ((x > y) ? 1 : 0));
- }
- tagArrayKeys = tagArrayKeys.sort(compare);
- for (var i = 0; i < tagArrayKeys.length; ++i) {
- newCssArray[tagName][tagArrayKeys[i]] = cssArray[tagName][tagArrayKeys[i]];
- }
- }
- }
- return newCssArray;
- },
-
/*
- * This function gets called when the toolbar is being updated
+ * This handler gets called when the editor has changed its mode to "wysiwyg"
*/
- onUpdateToolbar: function(button, mode, selectionEmpty, ancestors) {
- if (mode === "wysiwyg" && this.editor.isEditable()) {
- this.generate(this.editor, button.itemId);
+ onModeChange: function (mode) {
+ if (mode === 'wysiwyg' && this.editor.isEditable()) {
+ this.updateToolbar('TextStyle');
}
},
-
/*
* This function gets called when the drop-down list needs to be refreshed
*/
- updateToolbar : function(dropDownId) {
+ updateToolbar: function(dropDownId) {
var editor = this.editor;
if (this.getEditorMode() === "wysiwyg" && this.editor.isEditable()) {
var tagName = false, classNames = Array(), fullNodeSelected = false;
@@ -475,11 +310,10 @@
}
}
},
-
/*
* This function reinitializes the options of the dropdown
*/
- initializeDropDown : function (dropDown) {
+ initializeDropDown: function (dropDown) {
var store = dropDown.getStore();
store.removeAll(false);
store.insert(0, new store.recordType({
@@ -488,11 +322,10 @@
}));
dropDown.setValue('none');
},
-
/*
* This function sets the selected option of the dropDown box
*/
- setSelectedOption : function (dropDown, classNames, noUnknown, defaultClass) {
+ setSelectedOption: function (dropDown, classNames, noUnknown, defaultClass) {
var store = dropDown.getStore();
var index = store.findExact('value', classNames[classNames.length-1]);
if (index != -1) {
@@ -519,95 +352,36 @@
return true;
});
},
-
- updateValue : function(dropDownId, tagName, classNames, selectionEmpty, fullNodeSelected, disabled) {
+ /*
+ * This function updates the current value of the dropdown list
+ */
+ updateValue: function (dropDownId, nodeName, classNames, selectionEmpty, fullNodeSelected, disabled) {
var editor = this.editor;
var dropDown = this.getButton(dropDownId);
if (dropDown) {
var store = dropDown.getStore();
- var cssArray = new Array();
this.initializeDropDown(dropDown);
- if (this.REInlineTags.test(tagName)) {
- // Get classes allowed for all tags
- if (typeof(this.cssArray["all"]) !== "undefined") {
- var cssArrayAll = this.cssArray.all;
- if (this.tags && this.tags[tagName] && this.tags[tagName].allowedClasses) {
- var allowedClasses = this.tags[tagName].allowedClasses;
- for (var cssClass in cssArrayAll) {
- if (cssArrayAll.hasOwnProperty(cssClass) && allowedClasses.test(cssClass)) {
- cssArray[cssClass] = cssArrayAll[cssClass];
- }
- }
- } else {
- for (var cssClass in cssArrayAll) {
- if (cssArrayAll.hasOwnProperty(cssClass)) {
- cssArray[cssClass] = cssArrayAll[cssClass];
- }
- }
+ if (this.textStyles.isReady) {
+ var allowedClasses = {};
+ if (this.REInlineTags.test(nodeName)) {
+ if (Ext.isDefined(this.cssArray[nodeName])) {
+ allowedClasses = this.cssArray[nodeName];
+ } else if (this.showTagFreeClasses && Ext.isDefined(this.cssArray['all'])) {
+ allowedClasses = this.cssArray['all'];
}
}
- // Merge classes allowed for tagName and sort the array
- if (typeof(this.cssArray[tagName]) !== "undefined") {
- var cssArrayTagName = this.cssArray[tagName];
- if (this.tags && this.tags[tagName] && this.tags[tagName].allowedClasses) {
- var allowedClasses = this.tags[tagName].allowedClasses;
- for (var cssClass in cssArrayTagName) {
- if (cssArrayTagName.hasOwnProperty(cssClass) && allowedClasses.test(cssClass)) {
- cssArray[cssClass] = cssArrayTagName[cssClass];
- }
- }
- } else {
- for (var cssClass in cssArrayTagName) {
- if (cssArrayTagName.hasOwnProperty(cssClass)) {
- cssArray[cssClass] = cssArrayTagName[cssClass];
- }
- }
- }
- var sortedCssArray = new Object();
- var cssArrayKeys = new Array();
- for (var cssClass in cssArray) {
- if (cssArray.hasOwnProperty(cssClass)) {
- cssArrayKeys.push(cssClass);
- }
- }
- function compare(a, b) {
- x = cssArray[a];
- y = cssArray[b];
- return ((x < y) ? -1 : ((x > y) ? 1 : 0));
- }
- cssArrayKeys = cssArrayKeys.sort(compare);
- for (var i = 0; i < cssArrayKeys.length; ++i) {
- sortedCssArray[cssArrayKeys[i]] = cssArray[cssArrayKeys[i]];
- }
- cssArray = sortedCssArray;
- }
- for (var cssClass in cssArray) {
- if (cssArray.hasOwnProperty(cssClass) && cssArray[cssClass]) {
- if (cssClass == 'none') {
- store.getAt(0).set('text', cssArray[cssClass]);
- } else {
- store.add(new store.recordType({
- text: cssArray[cssClass],
- value: cssClass,
- style: (!this.editor.config.disablePCexamples && HTMLArea.classesValues && HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) ? HTMLArea.classesValues[cssClass] : null
- }));
- }
- }
- }
- if (classNames.length && (selectionEmpty || fullNodeSelected)) {
- this.setSelectedOption(dropDown, classNames);
- }
+ Ext.iterate(allowedClasses, function (cssClass, value) {
+ store.add(new store.recordType({
+ text: value,
+ value: cssClass,
+ style: (!this.editor.config.disablePCexamples && HTMLArea.classesValues && HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) ? HTMLArea.classesValues[cssClass] : null
+ }));
+ }, this);
}
+ if (classNames.length && (selectionEmpty || fullNodeSelected)) {
+ this.setSelectedOption(dropDown, classNames);
+ }
dropDown.setDisabled(!(store.getCount()>1) || disabled);
}
- },
- /*
- * This function gets called when the editor has changed its mode to "wysiwyg"
- */
- onModeChange: function(mode) {
- if (mode === "wysiwyg" && this.editor.isEditable()) {
- this.generate(this.editor, "TextStyle");
- }
}
});
-