5e7ed2001343a5d48a4667ec20fd6d63f42490b5
[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     {
611         var t = this;
612         return text.replace(attr ? this.attrsCharsRegExp : this.textCharsRegExp, function(chr) {
613             return t.baseEntities[chr] || chr;
614         });
615     },
616     /**
617      * Encoded the specified text with both the attributes and text entities. This function will produce larger text contents
618      * since it doesn't know if the context is within a attribute or text node. This was added for compatibility
619      * and is exposed as the DOMUtils.encode function.
620      *
621      * @method encodeAllRaw
622      * @param {String} text Text to encode.
623      * @return {String} Entity encoded text.
624      */
625     encodeAllRaw: function(text) {
626         var t = this;
627         return ('' + text).replace(this.rawCharsRegExp, function(chr) {
628             return t.baseEntities[chr] || chr;
629         });
630     },
631     /**
632      * Encodes the specified string using numeric entities. The core entities will be
633      * encoded as named ones but all non lower ascii characters will be encoded into numeric entities.
634      *
635      * @method encodeNumeric
636      * @param {String} text Text to encode.
637      * @param {Boolean} attr Optional flag to specify if the text is attribute contents.
638      * @return {String} Entity encoded text.
639      */
640     encodeNumeric: function(text, attr) {
641         var t = this;
642         return text.replace(attr ? this.attrsCharsRegExp : this.textCharsRegExp, function(chr) {
643             // Multi byte sequence convert it to a single entity
644             if (chr.length > 1) {
645                 return '&#' + (1024 * (chr.charCodeAt(0) - 55296) + (chr.charCodeAt(1) - 56320) + 65536) + ';';
646             }
647             return t.baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';';
648         });
649     },
650     /**
651      * Encodes the specified string using named entities. The core entities will be encoded
652      * as named ones but all non lower ascii characters will be encoded into named entities.
653      *
654      * @method encodeNamed
655      * @param {String} text Text to encode.
656      * @param {Boolean} attr Optional flag to specify if the text is attribute contents.
657      * @param {Object} entities Optional parameter with entities to use.
658      * @return {String} Entity encoded text.
659      */
660     encodeNamed: function(text, attr, entities) {
661         var t = this;
662         entities = entities || this.namedEntities;
663         return text.replace(attr ? this.attrsCharsRegExp : this.textCharsRegExp, function(chr) {
664             return t.baseEntities[chr] || entities[chr] || chr;
665         });
666     },
667     /**
668      * Returns an encode function based on the name(s) and it's optional entities.
669      *
670      * @method getEncodeFunc
671      * @param {String} name Comma separated list of encoders for example named,numeric.
672      * @param {String} entities Optional parameter with entities to use instead of the built in set.
673      * @return {function} Encode function to be used.
674      */
675     getEncodeFunc: function(name, entities) {
676         entities = this.buildEntitiesLookup(entities) || this.namedEntities;
677
678         function encodeNamedAndNumeric(text, attr) {
679             return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) {
680                 return baseEntities[chr] || entities[chr] || '&#' + chr.charCodeAt(0) + ';' || chr;
681             });
682         }
683
684         function encodeCustomNamed(text, attr) {
685             return Entities.encodeNamed(text, attr, entities);
686         }
687         // Replace + with , to be compatible with previous TinyMCE versions
688         name = makeMap(name.replace(/\+/g, ','));
689         // Named and numeric encoder
690         if (name.named && name.numeric) {
691             return encodeNamedAndNumeric;
692         }
693         // Named encoder
694         if (name.named) {
695             // Custom names
696             if (entities) {
697                 return encodeCustomNamed;
698             }
699             return Entities.encodeNamed;
700         }
701         // Numeric
702         if (name.numeric) {
703             return Entities.encodeNumeric;
704         }
705         // Raw encoder
706         return Entities.encodeRaw;
707     },
708     /**
709      * Decodes the specified string, this will replace entities with raw UTF characters.
710      *
711      * @method decode
712      * @param {String} text Text to entity decode.
713      * @return {String} Entity decoded string.
714      */
715     decode: function(text) {
716         return text.replace(entityRegExp, function(all, numeric) {
717             if (numeric) {
718                 numeric = 'x' === numeric.charAt(0).toLowerCase() ? parseInt(numeric.substr(1), 16) : parseInt(numeric, 10);
719                 // Support upper UTF
720                 if (numeric > 65535) {
721                     numeric -= 65536;
722                     return String.fromCharCode(55296 + (numeric >> 10), 56320 + (1023 & numeric));
723                 }
724                 return asciiMap[numeric] || String.fromCharCode(numeric);
725             }
726             return reverseEntities[all] || namedEntities[all] || nativeDecode(all);
727         });
728     }
729     function nativeDecode(text) {
730         return text;
731     }
732
733     
734     
735     
736 Roo.htmleditor.TidyEntities.init();