Roo/htmleditor/TidyEntities.js
[roojs1] / Roo / htmleditor / TidyEntities.js
1 /***
2  * This is based loosely on tinymce 
3  * @class Roo.htmleditor.TidyEntities
4  * @static
5  * https://github.com/thorn0/tinymce.html/blob/master/tinymce.html.js
6  */
7
8 Roo.htmleditor.TidyEntities = {
9     
10     /**
11      * initialize data..
12      */
13     init : function (){
14     
15         
16        // Decodes text by using the browser
17        
18        // Build a two way lookup table for the entities
19        
20        // Unpack entities lookup where the numbers are in radix 32 to reduce the size
21        
22       
23        this.namedEntities = buildEntitiesLookup(this.namedEntitiesData, 32);
24        
25     },
26
27
28      buildEntitiesLookup: function(items, radix) {
29         var i, chr, entity, lookup = {};
30         if (items) {
31             items = items.split(',');
32             radix = radix || 10;
33             // Build entities lookup table
34             for (i = 0; i < items.length; i += 2) {
35                 chr = String.fromCharCode(parseInt(items[i], radix));
36                 // Only add non base entities
37                 if (!baseEntities[chr]) {
38                     entity = '&' + items[i + 1] + ';';
39                     lookup[chr] = entity;
40                     lookup[entity] = chr;
41                 }
42             }
43             return lookup;
44         }
45         return {};
46     },
47     
48     asciiMap : {
49             128: '€',
50             130: '‚',
51             131: 'ƒ',
52             132: '„',
53             133: '…',
54             134: '†',
55             135: '‡',
56             136: 'ˆ',
57             137: '‰',
58             138: 'Š',
59             139: '‹',
60             140: 'Œ',
61             142: 'Ž',
62             145: '‘',
63             146: '’',
64             147: '“',
65             148: '”',
66             149: '•',
67             150: '–',
68             151: '—',
69             152: '˜',
70             153: '™',
71             154: 'š',
72             155: '›',
73             156: 'œ',
74             158: 'ž',
75             159: 'Ÿ'
76     },
77     // Raw entities
78     baseEntities : {
79         '"': '&quot;',
80         // Needs to be escaped since the YUI compressor would otherwise break the code
81         '\'': '&#39;',
82         '<': '&lt;',
83         '>': '&gt;',
84         '&': '&amp;',
85         '`': '&#96;'
86     },
87     // Reverse lookup table for raw entities
88     reverseEntities : {
89         '&lt;': '<',
90         '&gt;': '>',
91         '&amp;': '&',
92         '&quot;': '"',
93         '&apos;': '\''
94     },
95     
96     attrsCharsRegExp : /[&<>\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
97     textCharsRegExp : /[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
98     rawCharsRegExp : /[<>&\"\']/g,
99     entityRegExp : /&#([a-z0-9]+);?|&([a-z0-9]+);/gi,
100     namedEntities  : false,
101     namedEntitiesData : [ 
102         '50',
103         'nbsp',
104         '51',
105         'iexcl',
106         '52',
107         'cent',
108         '53',
109         'pound',
110         '54',
111         'curren',
112         '55',
113         'yen',
114         '56',
115         'brvbar',
116         '57',
117         'sect',
118         '58',
119         'uml',
120         '59',
121         'copy',
122         '5a',
123         'ordf',
124         '5b',
125         'laquo',
126         '5c',
127         'not',
128         '5d',
129         'shy',
130         '5e',
131         'reg',
132         '5f',
133         'macr',
134         '5g',
135         'deg',
136         '5h',
137         'plusmn',
138         '5i',
139         'sup2',
140         '5j',
141         'sup3',
142         '5k',
143         'acute',
144         '5l',
145         'micro',
146         '5m',
147         'para',
148         '5n',
149         'middot',
150         '5o',
151         'cedil',
152         '5p',
153         'sup1',
154         '5q',
155         'ordm',
156         '5r',
157         'raquo',
158         '5s',
159         'frac14',
160         '5t',
161         'frac12',
162         '5u',
163         'frac34',
164         '5v',
165         'iquest',
166         '60',
167         'Agrave',
168         '61',
169         'Aacute',
170         '62',
171         'Acirc',
172         '63',
173         'Atilde',
174         '64',
175         'Auml',
176         '65',
177         'Aring',
178         '66',
179         'AElig',
180         '67',
181         'Ccedil',
182         '68',
183         'Egrave',
184         '69',
185         'Eacute',
186         '6a',
187         'Ecirc',
188         '6b',
189         'Euml',
190         '6c',
191         'Igrave',
192         '6d',
193         'Iacute',
194         '6e',
195         'Icirc',
196         '6f',
197         'Iuml',
198         '6g',
199         'ETH',
200         '6h',
201         'Ntilde',
202         '6i',
203         'Ograve',
204         '6j',
205         'Oacute',
206         '6k',
207         'Ocirc',
208         '6l',
209         'Otilde',
210         '6m',
211         'Ouml',
212         '6n',
213         'times',
214         '6o',
215         'Oslash',
216         '6p',
217         'Ugrave',
218         '6q',
219         'Uacute',
220         '6r',
221         'Ucirc',
222         '6s',
223         'Uuml',
224         '6t',
225         'Yacute',
226         '6u',
227         'THORN',
228         '6v',
229         'szlig',
230         '70',
231         'agrave',
232         '71',
233         'aacute',
234         '72',
235         'acirc',
236         '73',
237         'atilde',
238         '74',
239         'auml',
240         '75',
241         'aring',
242         '76',
243         'aelig',
244         '77',
245         'ccedil',
246         '78',
247         'egrave',
248         '79',
249         'eacute',
250         '7a',
251         'ecirc',
252         '7b',
253         'euml',
254         '7c',
255         'igrave',
256         '7d',
257         'iacute',
258         '7e',
259         'icirc',
260         '7f',
261         'iuml',
262         '7g',
263         'eth',
264         '7h',
265         'ntilde',
266         '7i',
267         'ograve',
268         '7j',
269         'oacute',
270         '7k',
271         'ocirc',
272         '7l',
273         'otilde',
274         '7m',
275         'ouml',
276         '7n',
277         'divide',
278         '7o',
279         'oslash',
280         '7p',
281         'ugrave',
282         '7q',
283         'uacute',
284         '7r',
285         'ucirc',
286         '7s',
287         'uuml',
288         '7t',
289         'yacute',
290         '7u',
291         'thorn',
292         '7v',
293         'yuml',
294         'ci',
295         'fnof',
296         'sh',
297         'Alpha',
298         'si',
299         'Beta',
300         'sj',
301         'Gamma',
302         'sk',
303         'Delta',
304         'sl',
305         'Epsilon',
306         'sm',
307         'Zeta',
308         'sn',
309         'Eta',
310         'so',
311         'Theta',
312         'sp',
313         'Iota',
314         'sq',
315         'Kappa',
316         'sr',
317         'Lambda',
318         'ss',
319         'Mu',
320         'st',
321         'Nu',
322         'su',
323         'Xi',
324         'sv',
325         'Omicron',
326         't0',
327         'Pi',
328         't1',
329         'Rho',
330         't3',
331         'Sigma',
332         't4',
333         'Tau',
334         't5',
335         'Upsilon',
336         't6',
337         'Phi',
338         't7',
339         'Chi',
340         't8',
341         'Psi',
342         't9',
343         'Omega',
344         'th',
345         'alpha',
346         'ti',
347         'beta',
348         'tj',
349         'gamma',
350         'tk',
351         'delta',
352         'tl',
353         'epsilon',
354         'tm',
355         'zeta',
356         'tn',
357         'eta',
358         'to',
359         'theta',
360         'tp',
361         'iota',
362         'tq',
363         'kappa',
364         'tr',
365         'lambda',
366         'ts',
367         'mu',
368         'tt',
369         'nu',
370         'tu',
371         'xi',
372         'tv',
373         'omicron',
374         'u0',
375         'pi',
376         'u1',
377         'rho',
378         'u2',
379         'sigmaf',
380         'u3',
381         'sigma',
382         'u4',
383         'tau',
384         'u5',
385         'upsilon',
386         'u6',
387         'phi',
388         'u7',
389         'chi',
390         'u8',
391         'psi',
392         'u9',
393         'omega',
394         'uh',
395         'thetasym',
396         'ui',
397         'upsih',
398         'um',
399         'piv',
400         '812',
401         'bull',
402         '816',
403         'hellip',
404         '81i',
405         'prime',
406         '81j',
407         'Prime',
408         '81u',
409         'oline',
410         '824',
411         'frasl',
412         '88o',
413         'weierp',
414         '88h',
415         'image',
416         '88s',
417         'real',
418         '892',
419         'trade',
420         '89l',
421         'alefsym',
422         '8cg',
423         'larr',
424         '8ch',
425         'uarr',
426         '8ci',
427         'rarr',
428         '8cj',
429         'darr',
430         '8ck',
431         'harr',
432         '8dl',
433         'crarr',
434         '8eg',
435         'lArr',
436         '8eh',
437         'uArr',
438         '8ei',
439         'rArr',
440         '8ej',
441         'dArr',
442         '8ek',
443         'hArr',
444         '8g0',
445         'forall',
446         '8g2',
447         'part',
448         '8g3',
449         'exist',
450         '8g5',
451         'empty',
452         '8g7',
453         'nabla',
454         '8g8',
455         'isin',
456         '8g9',
457         'notin',
458         '8gb',
459         'ni',
460         '8gf',
461         'prod',
462         '8gh',
463         'sum',
464         '8gi',
465         'minus',
466         '8gn',
467         'lowast',
468         '8gq',
469         'radic',
470         '8gt',
471         'prop',
472         '8gu',
473         'infin',
474         '8h0',
475         'ang',
476         '8h7',
477         'and',
478         '8h8',
479         'or',
480         '8h9',
481         'cap',
482         '8ha',
483         'cup',
484         '8hb',
485         'int',
486         '8hk',
487         'there4',
488         '8hs',
489         'sim',
490         '8i5',
491         'cong',
492         '8i8',
493         'asymp',
494         '8j0',
495         'ne',
496         '8j1',
497         'equiv',
498         '8j4',
499         'le',
500         '8j5',
501         'ge',
502         '8k2',
503         'sub',
504         '8k3',
505         'sup',
506         '8k4',
507         'nsub',
508         '8k6',
509         'sube',
510         '8k7',
511         'supe',
512         '8kl',
513         'oplus',
514         '8kn',
515         'otimes',
516         '8l5',
517         'perp',
518         '8m5',
519         'sdot',
520         '8o8',
521         'lceil',
522         '8o9',
523         'rceil',
524         '8oa',
525         'lfloor',
526         '8ob',
527         'rfloor',
528         '8p9',
529         'lang',
530         '8pa',
531         'rang',
532         '9ea',
533         'loz',
534         '9j0',
535         'spades',
536         '9j3',
537         'clubs',
538         '9j5',
539         'hearts',
540         '9j6',
541         'diams',
542         'ai',
543         'OElig',
544         'aj',
545         'oelig',
546         'b0',
547         'Scaron',
548         'b1',
549         'scaron',
550         'bo',
551         'Yuml',
552         'm6',
553         'circ',
554         'ms',
555         'tilde',
556         '802',
557         'ensp',
558         '803',
559         'emsp',
560         '809',
561         'thinsp',
562         '80c',
563         'zwnj',
564         '80d',
565         'zwj',
566         '80e',
567         'lrm',
568         '80f',
569         'rlm',
570         '80j',
571         'ndash',
572         '80k',
573         'mdash',
574         '80o',
575         'lsquo',
576         '80p',
577         'rsquo',
578         '80q',
579         'sbquo',
580         '80s',
581         'ldquo',
582         '80t',
583         'rdquo',
584         '80u',
585         'bdquo',
586         '810',
587         'dagger',
588         '811',
589         'Dagger',
590         '81g',
591         'permil',
592         '81p',
593         'lsaquo',
594         '81q',
595         'rsaquo',
596         '85c',
597         'euro'
598     ] 
599
600          
601     /**
602      * Encodes the specified string using raw entities. This means only the required XML base entities will be encoded.
603      *
604      * @method encodeRaw
605      * @param {String} text Text to encode.
606      * @param {Boolean} attr Optional flag to specify if the text is attribute contents.
607      * @return {String} Entity encoded text.
608      */
609     encodeRaw: function(text, attr) {
610         return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) {
611             return baseEntities[chr] || chr;
612         });
613     },
614     /**
615      * Encoded the specified text with both the attributes and text entities. This function will produce larger text contents
616      * since it doesn't know if the context is within a attribute or text node. This was added for compatibility
617      * and is exposed as the DOMUtils.encode function.
618      *
619      * @method encodeAllRaw
620      * @param {String} text Text to encode.
621      * @return {String} Entity encoded text.
622      */
623     encodeAllRaw: function(text) {
624         return ('' + text).replace(rawCharsRegExp, function(chr) {
625             return baseEntities[chr] || chr;
626         });
627     },
628     /**
629      * Encodes the specified string using numeric entities. The core entities will be
630      * encoded as named ones but all non lower ascii characters will be encoded into numeric entities.
631      *
632      * @method encodeNumeric
633      * @param {String} text Text to encode.
634      * @param {Boolean} attr Optional flag to specify if the text is attribute contents.
635      * @return {String} Entity encoded text.
636      */
637     encodeNumeric: function(text, attr) {
638         return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) {
639             // Multi byte sequence convert it to a single entity
640             if (chr.length > 1) {
641                 return '&#' + (1024 * (chr.charCodeAt(0) - 55296) + (chr.charCodeAt(1) - 56320) + 65536) + ';';
642             }
643             return baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';';
644         });
645     },
646     /**
647      * Encodes the specified string using named entities. The core entities will be encoded
648      * as named ones but all non lower ascii characters will be encoded into named entities.
649      *
650      * @method encodeNamed
651      * @param {String} text Text to encode.
652      * @param {Boolean} attr Optional flag to specify if the text is attribute contents.
653      * @param {Object} entities Optional parameter with entities to use.
654      * @return {String} Entity encoded text.
655      */
656     encodeNamed: function(text, attr, entities) {
657         entities = entities || namedEntities;
658         return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) {
659             return baseEntities[chr] || entities[chr] || chr;
660         });
661     },
662     /**
663      * Returns an encode function based on the name(s) and it's optional entities.
664      *
665      * @method getEncodeFunc
666      * @param {String} name Comma separated list of encoders for example named,numeric.
667      * @param {String} entities Optional parameter with entities to use instead of the built in set.
668      * @return {function} Encode function to be used.
669      */
670     getEncodeFunc: function(name, entities) {
671         entities = buildEntitiesLookup(entities) || namedEntities;
672
673         function encodeNamedAndNumeric(text, attr) {
674             return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) {
675                 return baseEntities[chr] || entities[chr] || '&#' + chr.charCodeAt(0) + ';' || chr;
676             });
677         }
678
679         function encodeCustomNamed(text, attr) {
680             return Entities.encodeNamed(text, attr, entities);
681         }
682         // Replace + with , to be compatible with previous TinyMCE versions
683         name = makeMap(name.replace(/\+/g, ','));
684         // Named and numeric encoder
685         if (name.named && name.numeric) {
686             return encodeNamedAndNumeric;
687         }
688         // Named encoder
689         if (name.named) {
690             // Custom names
691             if (entities) {
692                 return encodeCustomNamed;
693             }
694             return Entities.encodeNamed;
695         }
696         // Numeric
697         if (name.numeric) {
698             return Entities.encodeNumeric;
699         }
700         // Raw encoder
701         return Entities.encodeRaw;
702     },
703     /**
704      * Decodes the specified string, this will replace entities with raw UTF characters.
705      *
706      * @method decode
707      * @param {String} text Text to entity decode.
708      * @return {String} Entity decoded string.
709      */
710     decode: function(text) {
711         return text.replace(entityRegExp, function(all, numeric) {
712             if (numeric) {
713                 numeric = 'x' === numeric.charAt(0).toLowerCase() ? parseInt(numeric.substr(1), 16) : parseInt(numeric, 10);
714                 // Support upper UTF
715                 if (numeric > 65535) {
716                     numeric -= 65536;
717                     return String.fromCharCode(55296 + (numeric >> 10), 56320 + (1023 & numeric));
718                 }
719                 return asciiMap[numeric] || String.fromCharCode(numeric);
720             }
721             return reverseEntities[all] || namedEntities[all] || nativeDecode(all);
722         });
723     }
724     function nativeDecode(text) {
725         return text;
726     }
727
728     
729     
730     
731 Roo.htmleditor.TidyEntities.init();