2 * This is based loosely on tinymce
3 * @class Roo.htmleditor.TidyEntities
5 * https://github.com/thorn0/tinymce.html/blob/master/tinymce.html.js
8 Roo.htmleditor.TidyEntities = {
17 this.namedEntities = buildEntitiesLookup(this.namedEntitiesData.join(','), 32);
22 buildEntitiesLookup: function(items, radix) {
23 var i, chr, entity, lookup = {};
25 items = items.split(',');
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] + ';';
74 // Needs to be escaped since the YUI compressor would otherwise break the code
81 // Reverse lookup table for raw entities
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,
596 * Encodes the specified string using raw entities. This means only the required XML base entities will be encoded.
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.
603 encodeRaw: function(text, attr)
606 return text.replace(attr ? this.attrsCharsRegExp : this.textCharsRegExp, function(chr) {
607 return t.baseEntities[chr] || chr;
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.
615 * @method encodeAllRaw
616 * @param {String} text Text to encode.
617 * @return {String} Entity encoded text.
619 encodeAllRaw: function(text) {
621 return ('' + text).replace(this.rawCharsRegExp, function(chr) {
622 return t.baseEntities[chr] || chr;
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.
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.
634 encodeNumeric: function(text, attr) {
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) + ';';
641 return t.baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';';
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.
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.
654 encodeNamed: function(text, attr, entities) {
656 entities = entities || this.namedEntities;
657 return text.replace(attr ? this.attrsCharsRegExp : this.textCharsRegExp, function(chr) {
658 return t.baseEntities[chr] || entities[chr] || chr;
662 * Returns an encode function based on the name(s) and it's optional entities.
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.
669 getEncodeFunc: function(name, entities) {
670 entities = this.buildEntitiesLookup(entities) || this.namedEntities;
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;
678 function encodeCustomNamed(text, attr) {
679 return t.encodeNamed(text, attr, entities);
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;
691 return encodeCustomNamed;
693 return this.encodeNamed;
697 return this.encodeNumeric;
700 return this.encodeRaw;
703 * Decodes the specified string, this will replace entities with raw UTF characters.
706 * @param {String} text Text to entity decode.
707 * @return {String} Entity decoded string.
709 decode: function(text)
712 return text.replace(this.entityRegExp, function(all, numeric) {
714 numeric = 'x' === numeric.charAt(0).toLowerCase() ? parseInt(numeric.substr(1), 16) : parseInt(numeric, 10);
716 if (numeric > 65535) {
718 return String.fromCharCode(55296 + (numeric >> 10), 56320 + (1023 & numeric));
720 return t.asciiMap[numeric] || String.fromCharCode(numeric);
722 return t.reverseEntities[all] || t.namedEntities[all] || t.nativeDecode(all);
725 nativeDecode : function (text) {
728 makeMap : function (items, delim, map) {
731 delim = delim || ',';
732 if (typeof items == "string") {
733 items = items.split(delim);
746 Roo.htmleditor.TidyEntities.init();