diff options
Diffstat (limited to 'sources/core/filter.js')
-rw-r--r-- | sources/core/filter.js | 159 |
1 files changed, 143 insertions, 16 deletions
diff --git a/sources/core/filter.js b/sources/core/filter.js index e9d5a37..3e64fc5 100644 --- a/sources/core/filter.js +++ b/sources/core/filter.js | |||
@@ -1,5 +1,5 @@ | |||
1 | /** | 1 | /** |
2 | * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved. | 2 | * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. |
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license | 3 | * For licensing, see LICENSE.md or http://ckeditor.com/license |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -158,7 +158,8 @@ | |||
158 | }, | 158 | }, |
159 | // Object: element name => array of transformations groups. | 159 | // Object: element name => array of transformations groups. |
160 | transformations: {}, | 160 | transformations: {}, |
161 | cachedTests: {} | 161 | cachedTests: {}, |
162 | cachedChecks: {} | ||
162 | }; | 163 | }; |
163 | 164 | ||
164 | // Register filter instance. | 165 | // Register filter instance. |
@@ -299,7 +300,7 @@ | |||
299 | if ( el.attributes[ 'data-cke-filter' ] == 'off' ) | 300 | if ( el.attributes[ 'data-cke-filter' ] == 'off' ) |
300 | return false; | 301 | return false; |
301 | 302 | ||
302 | // (#10260) Don't touch elements like spans with data-cke-* attribute since they're | 303 | // (http://dev.ckeditor.com/ticket/10260) Don't touch elements like spans with data-cke-* attribute since they're |
303 | // responsible e.g. for placing markers, bookmarks, odds and stuff. | 304 | // responsible e.g. for placing markers, bookmarks, odds and stuff. |
304 | // We love 'em and we don't wanna lose anything during the filtering. | 305 | // We love 'em and we don't wanna lose anything during the filtering. |
305 | // '|' is to avoid tricky joints like data-="foo" + cke-="bar". Yes, they're possible. | 306 | // '|' is to avoid tricky joints like data-="foo" + cke-="bar". Yes, they're possible. |
@@ -346,7 +347,7 @@ | |||
346 | if ( !element.parent ) | 347 | if ( !element.parent ) |
347 | continue; | 348 | continue; |
348 | 349 | ||
349 | // Handle custom elements as inline elements (#12683). | 350 | // Handle custom elements as inline elements (http://dev.ckeditor.com/ticket/12683). |
350 | parentDtd = DTD[ element.parent.name ] || DTD.span; | 351 | parentDtd = DTD[ element.parent.name ] || DTD.span; |
351 | 352 | ||
352 | switch ( check.check ) { | 353 | switch ( check.check ) { |
@@ -806,6 +807,32 @@ | |||
806 | } )(), | 807 | } )(), |
807 | 808 | ||
808 | /** | 809 | /** |
810 | * Returns a clone of this filter instance. | ||
811 | * | ||
812 | * @since 4.7.3 | ||
813 | * @returns {CKEDITOR.filter} | ||
814 | */ | ||
815 | clone: function() { | ||
816 | var ret = new CKEDITOR.filter(), | ||
817 | clone = CKEDITOR.tools.clone; | ||
818 | |||
819 | // Cloning allowed content related things. | ||
820 | ret.allowedContent = clone( this.allowedContent ); | ||
821 | ret._.allowedRules = clone( this._.allowedRules ); | ||
822 | |||
823 | // Disallowed content rules. | ||
824 | ret.disallowedContent = clone( this.disallowedContent ); | ||
825 | ret._.disallowedRules = clone( this._.disallowedRules ); | ||
826 | |||
827 | ret._.transformations = clone( this._.transformations ); | ||
828 | |||
829 | ret.disabled = this.disabled; | ||
830 | ret.editor = this.editor; | ||
831 | |||
832 | return ret; | ||
833 | }, | ||
834 | |||
835 | /** | ||
809 | * Destroys the filter instance and removes it from the global {@link CKEDITOR.filter#instances} object. | 836 | * Destroys the filter instance and removes it from the global {@link CKEDITOR.filter#instances} object. |
810 | * | 837 | * |
811 | * @since 4.4.5 | 838 | * @since 4.4.5 |
@@ -1248,22 +1275,20 @@ | |||
1248 | styles = styleDef.styles, | 1275 | styles = styleDef.styles, |
1249 | attrs = styleDef.attributes || {}; | 1276 | attrs = styleDef.attributes || {}; |
1250 | 1277 | ||
1251 | if ( styles ) { | 1278 | if ( styles && !CKEDITOR.tools.isEmpty( styles ) ) { |
1252 | styles = copy( styles ); | 1279 | styles = copy( styles ); |
1253 | attrs.style = CKEDITOR.tools.writeCssText( styles, true ); | 1280 | attrs.style = CKEDITOR.tools.writeCssText( styles, true ); |
1254 | } else { | 1281 | } else { |
1255 | styles = {}; | 1282 | styles = {}; |
1256 | } | 1283 | } |
1257 | 1284 | ||
1258 | var el = { | 1285 | return { |
1259 | name: styleDef.element, | 1286 | name: styleDef.element, |
1260 | attributes: attrs, | 1287 | attributes: attrs, |
1261 | classes: attrs[ 'class' ] ? attrs[ 'class' ].split( /\s+/ ) : [], | 1288 | classes: attrs[ 'class' ] ? attrs[ 'class' ].split( /\s+/ ) : [], |
1262 | styles: styles, | 1289 | styles: styles, |
1263 | children: [] | 1290 | children: [] |
1264 | }; | 1291 | }; |
1265 | |||
1266 | return el; | ||
1267 | } | 1292 | } |
1268 | 1293 | ||
1269 | // Mock hash based on string. | 1294 | // Mock hash based on string. |
@@ -1873,6 +1898,7 @@ | |||
1873 | // | 1898 | // |
1874 | // TRANSFORMATIONS -------------------------------------------------------- | 1899 | // TRANSFORMATIONS -------------------------------------------------------- |
1875 | // | 1900 | // |
1901 | var transformationsTools; | ||
1876 | 1902 | ||
1877 | // Apply given transformations group to the element. | 1903 | // Apply given transformations group to the element. |
1878 | function applyTransformationsGroup( filter, element, group ) { | 1904 | function applyTransformationsGroup( filter, element, group ) { |
@@ -2021,7 +2047,7 @@ | |||
2021 | * @class CKEDITOR.filter.transformationsTools | 2047 | * @class CKEDITOR.filter.transformationsTools |
2022 | * @singleton | 2048 | * @singleton |
2023 | */ | 2049 | */ |
2024 | var transformationsTools = CKEDITOR.filter.transformationsTools = { | 2050 | transformationsTools = CKEDITOR.filter.transformationsTools = { |
2025 | /** | 2051 | /** |
2026 | * Converts `width` and `height` attributes to styles. | 2052 | * Converts `width` and `height` attributes to styles. |
2027 | * | 2053 | * |
@@ -2070,8 +2096,8 @@ | |||
2070 | * Converts length in the `styleName` style to a valid length attribute (like `width` or `height`). | 2096 | * Converts length in the `styleName` style to a valid length attribute (like `width` or `height`). |
2071 | * | 2097 | * |
2072 | * @param {CKEDITOR.htmlParser.element} element | 2098 | * @param {CKEDITOR.htmlParser.element} element |
2073 | * @param {String} styleName Name of the style that will be converted. | 2099 | * @param {String} styleName The name of the style that will be converted. |
2074 | * @param {String} [attrName=styleName] Name of the attribute into which the style will be converted. | 2100 | * @param {String} [attrName=styleName] The name of the attribute into which the style will be converted. |
2075 | */ | 2101 | */ |
2076 | lengthToAttribute: function( element, styleName, attrName ) { | 2102 | lengthToAttribute: function( element, styleName, attrName ) { |
2077 | attrName = attrName || styleName; | 2103 | attrName = attrName || styleName; |
@@ -2091,7 +2117,7 @@ | |||
2091 | }, | 2117 | }, |
2092 | 2118 | ||
2093 | /** | 2119 | /** |
2094 | * Converts the `align` attribute to the `float` style if not set. Attribute | 2120 | * Converts the `align` attribute to the `float` style if not set. The attribute |
2095 | * is always removed. | 2121 | * is always removed. |
2096 | * | 2122 | * |
2097 | * @param {CKEDITOR.htmlParser.element} element | 2123 | * @param {CKEDITOR.htmlParser.element} element |
@@ -2109,7 +2135,7 @@ | |||
2109 | 2135 | ||
2110 | /** | 2136 | /** |
2111 | * Converts the `float` style to the `align` attribute if not set. | 2137 | * Converts the `float` style to the `align` attribute if not set. |
2112 | * Style is always removed. | 2138 | * The style is always removed. |
2113 | * | 2139 | * |
2114 | * @param {CKEDITOR.htmlParser.element} element | 2140 | * @param {CKEDITOR.htmlParser.element} element |
2115 | */ | 2141 | */ |
@@ -2125,6 +2151,107 @@ | |||
2125 | }, | 2151 | }, |
2126 | 2152 | ||
2127 | /** | 2153 | /** |
2154 | * Converts the shorthand form of the `border` style to seperate styles. | ||
2155 | * | ||
2156 | * @param {CKEDITOR.htmlParser.element} element | ||
2157 | */ | ||
2158 | splitBorderShorthand: function( element ) { | ||
2159 | if ( !element.styles.border ) { | ||
2160 | return; | ||
2161 | } | ||
2162 | |||
2163 | var widths = element.styles.border.match( /([\.\d]+\w+)/g ) || [ '0px' ]; | ||
2164 | switch ( widths.length ) { | ||
2165 | case 1: | ||
2166 | element.styles[ 'border-width' ] = widths[0]; | ||
2167 | break; | ||
2168 | case 2: | ||
2169 | mapStyles( [ 0, 1, 0, 1 ] ); | ||
2170 | break; | ||
2171 | case 3: | ||
2172 | mapStyles( [ 0, 1, 2, 1 ] ); | ||
2173 | break; | ||
2174 | case 4: | ||
2175 | mapStyles( [ 0, 1, 2, 3 ] ); | ||
2176 | break; | ||
2177 | } | ||
2178 | |||
2179 | element.styles[ 'border-style' ] = element.styles[ 'border-style' ] || | ||
2180 | ( element.styles.border.match( /(none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset|initial|inherit)/ ) || [] )[ 0 ]; | ||
2181 | if ( !element.styles[ 'border-style' ] ) | ||
2182 | delete element.styles[ 'border-style' ]; | ||
2183 | |||
2184 | delete element.styles.border; | ||
2185 | |||
2186 | function mapStyles( map ) { | ||
2187 | element.styles['border-top-width'] = widths[ map[0] ]; | ||
2188 | element.styles['border-right-width'] = widths[ map[1] ]; | ||
2189 | element.styles['border-bottom-width'] = widths[ map[2] ]; | ||
2190 | element.styles['border-left-width'] = widths[ map[3] ]; | ||
2191 | } | ||
2192 | }, | ||
2193 | |||
2194 | listTypeToStyle: function( element ) { | ||
2195 | if ( element.attributes.type ) { | ||
2196 | switch ( element.attributes.type ) { | ||
2197 | case 'a': | ||
2198 | element.styles[ 'list-style-type' ] = 'lower-alpha'; | ||
2199 | break; | ||
2200 | case 'A': | ||
2201 | element.styles[ 'list-style-type' ] = 'upper-alpha'; | ||
2202 | break; | ||
2203 | case 'i': | ||
2204 | element.styles[ 'list-style-type' ] = 'lower-roman'; | ||
2205 | break; | ||
2206 | case 'I': | ||
2207 | element.styles[ 'list-style-type' ] = 'upper-roman'; | ||
2208 | break; | ||
2209 | case '1': | ||
2210 | element.styles[ 'list-style-type' ] = 'decimal'; | ||
2211 | break; | ||
2212 | default: | ||
2213 | element.styles[ 'list-style-type' ] = element.attributes.type; | ||
2214 | } | ||
2215 | } | ||
2216 | }, | ||
2217 | |||
2218 | /** | ||
2219 | * Converts the shorthand form of the `margin` style to seperate styles. | ||
2220 | * | ||
2221 | * @param {CKEDITOR.htmlParser.element} element | ||
2222 | */ | ||
2223 | splitMarginShorthand: function( element ) { | ||
2224 | if ( !element.styles.margin ) { | ||
2225 | return; | ||
2226 | } | ||
2227 | |||
2228 | var widths = element.styles.margin.match( /(\-?[\.\d]+\w+)/g ) || [ '0px' ]; | ||
2229 | switch ( widths.length ) { | ||
2230 | case 1: | ||
2231 | mapStyles( [ 0, 0, 0, 0 ] ); | ||
2232 | break; | ||
2233 | case 2: | ||
2234 | mapStyles( [ 0, 1, 0, 1 ] ); | ||
2235 | break; | ||
2236 | case 3: | ||
2237 | mapStyles( [ 0, 1, 2, 1 ] ); | ||
2238 | break; | ||
2239 | case 4: | ||
2240 | mapStyles( [ 0, 1, 2, 3 ] ); | ||
2241 | break; | ||
2242 | } | ||
2243 | |||
2244 | delete element.styles.margin; | ||
2245 | |||
2246 | function mapStyles( map ) { | ||
2247 | element.styles['margin-top'] = widths[ map[0] ]; | ||
2248 | element.styles['margin-right'] = widths[ map[1] ]; | ||
2249 | element.styles['margin-bottom'] = widths[ map[2] ]; | ||
2250 | element.styles['margin-left'] = widths[ map[3] ]; | ||
2251 | } | ||
2252 | }, | ||
2253 | |||
2254 | /** | ||
2128 | * Checks whether an element matches a given {@link CKEDITOR.style}. | 2255 | * Checks whether an element matches a given {@link CKEDITOR.style}. |
2129 | * The element can be a "superset" of a style, e.g. it may have | 2256 | * The element can be a "superset" of a style, e.g. it may have |
2130 | * more classes, but needs to have at least those defined in the style. | 2257 | * more classes, but needs to have at least those defined in the style. |
@@ -2135,12 +2262,12 @@ | |||
2135 | matchesStyle: elementMatchesStyle, | 2262 | matchesStyle: elementMatchesStyle, |
2136 | 2263 | ||
2137 | /** | 2264 | /** |
2138 | * Transforms element to given form. | 2265 | * Transforms an element to a given form. |
2139 | * | 2266 | * |
2140 | * Form may be a: | 2267 | * Form may be a: |
2141 | * | 2268 | * |
2142 | * * {@link CKEDITOR.style}, | 2269 | * * {@link CKEDITOR.style}, |
2143 | * * string – the new name of an element. | 2270 | * * string – the new name of the element. |
2144 | * | 2271 | * |
2145 | * @param {CKEDITOR.htmlParser.element} el | 2272 | * @param {CKEDITOR.htmlParser.element} el |
2146 | * @param {CKEDITOR.style/String} form | 2273 | * @param {CKEDITOR.style/String} form |
@@ -2191,7 +2318,7 @@ | |||
2191 | * * {@link CKEDITOR.filter.allowedContentRules} – defined rules will be added | 2318 | * * {@link CKEDITOR.filter.allowedContentRules} – defined rules will be added |
2192 | * to the {@link CKEDITOR.editor#filter}. | 2319 | * to the {@link CKEDITOR.editor#filter}. |
2193 | * * `true` – will disable the filter (data will not be filtered, | 2320 | * * `true` – will disable the filter (data will not be filtered, |
2194 | * all features will be activated). | 2321 | * all features will be activated). Reading [security best practices](#!/guide/dev_best_practices) before setting `true` is recommended. |
2195 | * * default – the filter will be configured by loaded features | 2322 | * * default – the filter will be configured by loaded features |
2196 | * (toolbar items, commands, etc.). | 2323 | * (toolbar items, commands, etc.). |
2197 | * | 2324 | * |