--- /dev/null
+/*\r
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.html or http://ckeditor.com/license\r
+*/\r
+\r
+/**\r
+ * @stylesheetParser plugin.\r
+ */\r
+\r
+(function()\r
+{\r
+ // We want to extract only the elements with classes defined in the stylesheets:\r
+ function parseClasses( aRules, skipSelectors, validSelectors )\r
+ {\r
+ // aRules are just the different rules in the style sheets\r
+ // We want to merge them and them split them by commas, so we end up with only\r
+ // the selectors\r
+ var s = aRules.join(' ');\r
+ // Remove selectors splitting the elements, leave only the class selector (.)\r
+ s = s.replace( /(,|>|\+|~)/g, ' ' );\r
+ // Remove attribute selectors: table[border="0"]\r
+ s = s.replace( /\[[^\]]*/g, '' );\r
+ // Remove Ids: div#main\r
+ s = s.replace( /#[^\s]*/g, '' );\r
+ // Remove pseudo-selectors and pseudo-elements: :hover :nth-child(2n+1) ::before\r
+ s = s.replace( /\:{1,2}[^\s]*/g, '' );\r
+\r
+ s = s.replace( /\s+/g, ' ' );\r
+\r
+ var aSelectors = s.split( ' ' ),\r
+ aClasses = [];\r
+\r
+ for ( var i = 0; i < aSelectors.length ; i++ )\r
+ {\r
+ var selector = aSelectors[ i ];\r
+\r
+ if ( validSelectors.test( selector ) && !skipSelectors.test( selector ) )\r
+ {\r
+ // If we still don't know about this one, add it\r
+ if ( CKEDITOR.tools.indexOf( aClasses, selector ) == -1 )\r
+ aClasses.push( selector );\r
+ }\r
+ }\r
+\r
+ return aClasses;\r
+ }\r
+\r
+ function LoadStylesCSS( theDoc, skipSelectors, validSelectors )\r
+ {\r
+ var styles = [],\r
+ // It will hold all the rules of the applied stylesheets (except those internal to CKEditor)\r
+ aRules = [],\r
+ i;\r
+\r
+ for ( i = 0; i < theDoc.styleSheets.length; i++ )\r
+ {\r
+ var sheet = theDoc.styleSheets[ i ],\r
+ node = sheet.ownerNode || sheet.owningElement;\r
+\r
+ // Skip the internal stylesheets\r
+ if ( node.getAttribute( 'data-cke-temp' ) )\r
+ continue;\r
+\r
+ // Exclude stylesheets injected by extensions\r
+ if ( sheet.href && sheet.href.substr(0, 9) == 'chrome://' )\r
+ continue;\r
+\r
+ var sheetRules = sheet.cssRules || sheet.rules;\r
+ for ( var j = 0; j < sheetRules.length; j++ )\r
+ aRules.push( sheetRules[ j ].selectorText );\r
+ }\r
+\r
+ var aClasses = parseClasses( aRules, skipSelectors, validSelectors );\r
+\r
+ // Add each style to our "Styles" collection.\r
+ for ( i = 0; i < aClasses.length; i++ )\r
+ {\r
+ var oElement = aClasses[ i ].split( '.' ),\r
+ element = oElement[ 0 ].toLowerCase(),\r
+ sClassName = oElement[ 1 ];\r
+\r
+ styles.push( {\r
+ name : element + '.' + sClassName,\r
+ element : element,\r
+ attributes : {'class' : sClassName}\r
+ });\r
+ }\r
+\r
+ return styles;\r
+ }\r
+\r
+ // Register a plugin named "stylesheetparser".\r
+ CKEDITOR.plugins.add( 'stylesheetparser',\r
+ {\r
+ requires: [ 'styles' ],\r
+ onLoad : function()\r
+ {\r
+ var obj = CKEDITOR.editor.prototype;\r
+ obj.getStylesSet = CKEDITOR.tools.override( obj.getStylesSet, function( org )\r
+ {\r
+ return function( callback )\r
+ {\r
+ var self = this;\r
+ org.call( this, function( definitions )\r
+ {\r
+ // Rules that must be skipped\r
+ var skipSelectors = self.config.stylesheetParser_skipSelectors || ( /(^body\.|^\.)/i ),\r
+ // Rules that are valid\r
+ validSelectors = self.config.stylesheetParser_validSelectors || ( /\w+\.\w+/ );\r
+\r
+ callback( ( self._.stylesDefinitions = definitions.concat( LoadStylesCSS( self.document.$, skipSelectors, validSelectors ) ) ) );\r
+ });\r
+ };\r
+ });\r
+\r
+ }\r
+ });\r
+})();\r
+\r
+\r
+/**\r
+ * A regular expression that defines whether a CSS rule will be\r
+ * skipped by the Stylesheet Parser plugin. A CSS rule matching\r
+ * the regular expression will be ignored and will not be available\r
+ * in the Styles drop-down list.\r
+ * @name CKEDITOR.config.stylesheetParser_skipSelectors\r
+ * @type RegExp\r
+ * @default /(^body\.|^\.)/i\r
+ * @since 3.6\r
+ * @see CKEDITOR.config.stylesheetParser_validSelectors\r
+ * @example\r
+ * // Ignore rules for body and caption elements, classes starting with "high", and any class defined for no specific element.\r
+ * config.stylesheetParser_skipSelectors = /(^body\.|^caption\.|\.high|^\.)/i;\r
+ */\r
+\r
+ /**\r
+ * A regular expression that defines which CSS rules will be used\r
+ * by the Stylesheet Parser plugin. A CSS rule matching the regular\r
+ * expression will be available in the Styles drop-down list.\r
+ * @name CKEDITOR.config.stylesheetParser_validSelectors\r
+ * @type RegExp\r
+ * @default /\w+\.\w+/\r
+ * @since 3.6\r
+ * @see CKEDITOR.config.stylesheetParser_skipSelectors\r
+ * @example\r
+ * // Only add rules for p and span elements.\r
+ * config.stylesheetParser_validSelectors = /\^(p|span)\.\w+/;\r
+ */\r