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