Back to index

plone3  3.1.7
Public Member Functions | Public Attributes | Private Member Functions
kss.core.pluginregistry._concatresource.compression.thirdparty.packer.JavascriptKeywordMapper Class Reference
Inheritance diagram for kss.core.pluginregistry._concatresource.compression.thirdparty.packer.JavascriptKeywordMapper:
Inheritance graph
[legend]
Collaboration diagram for kss.core.pluginregistry._concatresource.compression.thirdparty.packer.JavascriptKeywordMapper:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __init__
def getDecodeFunction
def getDecoder
def analyseKeywords
def analyse
def getKeywords
def sub

Public Attributes

 regexp
 encoder
 mapping

Private Member Functions

def _encode

Detailed Description

Definition at line 116 of file packer.py.


Constructor & Destructor Documentation

Reimplemented from kss.core.pluginregistry._concatresource.compression.thirdparty.packer.KeywordMapper.

Definition at line 117 of file packer.py.

00117 
00118     def __init__(self, regexp=None, encoder=None):
00119         if regexp is None:
00120             self.regexp = re.compile(r'\w+')
00121         elif isinstance(regexp, (str, unicode)):
00122             self.regexp = re.compile(regexp)
00123         else:
00124             self.regexp = regexp
00125         if encoder is None:
00126             self.encoder = self._encode
00127         else:
00128             self.encoder = encoder
00129         self.mapping = {}

Here is the caller graph for this function:


Member Function Documentation

def kss.core.pluginregistry._concatresource.compression.thirdparty.packer.JavascriptKeywordMapper._encode (   self,
  charCode,
  mapping = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 
) [private]

Definition at line 131 of file packer.py.

00131 
00132                 mapping="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"):
00133         result = []
00134         quotient = charCode
00135         while quotient or not len(result):
00136             quotient, remainder = divmod(quotient, 62)
00137             result.append(mapping[remainder])
00138         result.reverse()
00139         return "".join(result)

Here is the caller graph for this function:

Definition at line 95 of file packer.py.

00095 
00096     def analyse(self, input):
00097         self.mapping = self.analyseKeywords(input)

Here is the call graph for this function:

Definition at line 36 of file packer.py.

00036 
00037     def analyseKeywords(self, input):
00038         matches = self.regexp.findall(input)
00039 
00040         protected = {}
00041         keyword_count = {}
00042         index = 0
00043         for match in matches:
00044             if match not in keyword_count:
00045                 keyword_count[match] = 0
00046                 protected[self.encoder(index)] = index
00047                 index = index + 1
00048             keyword_count[match] = keyword_count[match] + 1
00049 
00050         for match in matches:
00051             if match in protected and keyword_count[match]:
00052                 keyword_count[match] = 0
00053 
00054         protected = {}
00055         for match in keyword_count:
00056             if not keyword_count[match]:
00057                 protected[match] = None
00058 
00059         ## sorted_matches = [(c,len(v),v) for v,c in keyword_count.iteritems()]
00060         # the above line implements the original behaviour, the code below
00061         # removes keywords which have not enough weight to be encoded, in total
00062         # this saves some bytes, because the total length of the generated
00063         # codes is a bit smaller. This needs corresponding code in the
00064         # fast_decode javascript function of the decoder, see comment there
00065         sorted_matches = []
00066         for value, count in keyword_count.iteritems():
00067             weight = count * len(value)
00068             if len(value) >= weight:
00069                 keyword_count[value] = 0
00070                 sorted_matches.append((0, value))
00071             else:
00072                 sorted_matches.append((weight, value))
00073         sorted_matches.sort()
00074         sorted_matches.reverse()
00075         sorted_matches = [x[-1] for x in sorted_matches]
00076 
00077         index = 0
00078         mapping = {}
00079         for match in sorted_matches:
00080             if not keyword_count[match]:
00081                 if match not in protected:
00082                     mapping[match] = (-1, match)
00083                 continue
00084             while 1:
00085                 encoded = self.encoder(index)
00086                 index = index + 1
00087                 if encoded in protected:
00088                     mapping[encoded] = (index-1, encoded)
00089                     continue
00090                 else:
00091                     break
00092             mapping[match] = (index-1, encoded)
00093 
00094         return mapping

Here is the caller graph for this function:

Definition at line 140 of file packer.py.

00140 
00141     def getDecodeFunction(self, fast=True, name=None):
00142         jspacker = JavascriptPacker('full')
00143 
00144         # fast boot function
00145         fast_decoder = r"""
00146             // does the browser support String.replace where the
00147             //  replacement value is a function?
00148             if (!''.replace(/^/, String)) {
00149                 // decode all the values we need
00150                 // we have to add the dollar prefix, because $encoded can be
00151                 // any keyword in the decode function below. For example
00152                 // 'constructor' is an attribute of any object and it would
00153                 // return a false positive match in that case.
00154                 while ($count--) $decode["$"+$encode($count)] = $keywords[$count] || $encode($count);
00155                 // global replacement function
00156                 $keywords = [function($encoded){$result = $decode["$"+$encoded]; return $result!=undefined?$result:$encoded}];
00157                 // generic match
00158                 $encode = function(){return'\\w+'};
00159                 // reset the loop counter -  we are now doing a global replace
00160                 $count = 1;
00161             };"""
00162 
00163         if name is None:
00164             # boot function
00165             decoder = r"""
00166                 function($packed, $ascii, $count, $keywords, $encode, $decode) {
00167                     $encode = function($charCode) {
00168                         return ($charCode < $ascii ? "" : $encode(parseInt($charCode / $ascii))) +
00169                             (($charCode = $charCode % $ascii) > 35 ? String.fromCharCode($charCode + 29) : $charCode.toString(36));
00170                     };
00171                     // fastDecodePlaceholder
00172                     while ($count--)
00173                         if ($keywords[$count])
00174                             $packed = $packed.replace(new RegExp("\\b" + $encode($count) + "\\b", "g"), $keywords[$count]);
00175                     return $packed;
00176                 }"""
00177 
00178             if fast:
00179                 decoder = decoder.replace('// fastDecodePlaceholder', fast_decoder)
00180 
00181             decoder = jspacker.pack(decoder)
00182 
00183         else:
00184             decoder = r"""
00185                 var %s = function($ascii, $count, $keywords, $encode, $decode) {
00186                     $encode = function($charCode) {
00187                         return ($charCode < $ascii ? "" : $encode(parseInt($charCode / $ascii))) +
00188                             (($charCode = $charCode %% $ascii) > 35 ? String.fromCharCode($charCode + 29) : $charCode.toString(36));
00189                     };
00190                     // fastDecodePlaceholder
00191                     var decoder = function($packed, $ascii1, $count1, $keywords1, $encode1, $decode1) {
00192                         $count1 = $count;
00193                         while ($count1--)
00194                             if ($keywords[$count1])
00195                                 $packed = $packed.replace(new RegExp("\\b" + $encode($count1) + "\\b", "g"), $keywords[$count1]);
00196                         return $packed;
00197                     };
00198                     return decoder;
00199                 }""" % name
00200 
00201             if fast:
00202                 decoder = decoder.replace('// fastDecodePlaceholder', fast_decoder)
00203 
00204             decoder = jspacker.pack(decoder)
00205 
00206             keywords = self.getKeywords()
00207             decoder = "%s(62, %i, '%s'.split('|'), 0, {});" % (decoder, len(keywords), "|".join(keywords))
00208 
00209         return decoder

Here is the call graph for this function:

Here is the caller graph for this function:

def kss.core.pluginregistry._concatresource.compression.thirdparty.packer.JavascriptKeywordMapper.getDecoder (   self,
  input,
  keyword_var = None,
  decode_func = None 
)

Definition at line 210 of file packer.py.

00210 
00211     def getDecoder(self, input, keyword_var=None, decode_func=None):
00212         if keyword_var is None:
00213             keywords = self.getKeywords()
00214             num_keywords = len(keywords)
00215             keywords = "|".join(keywords)
00216             keywords = "'%s'.split('|')" % keywords
00217         else:
00218             keywords = keyword_var
00219             num_keywords = len(self.getKeywords())
00220 
00221         if decode_func is None:
00222             decode_func = self.getDecodeFunction()
00223 
00224         escaped_single = input.replace("\\","\\\\").replace("'","\\'").replace('\n','\\n')
00225         escaped_double = input.replace("\\","\\\\").replace('"','\\"').replace('\n','\\n')
00226         if len(escaped_single) < len(escaped_double):
00227             script = "'%s'" % escaped_single
00228         else:
00229             script = '"%s"' % escaped_double
00230         return "eval(%s(%s,62,%i,%s,0,{}))" % (decode_func, script,
00231                                                num_keywords,
00232                                                keywords)
00233 

Here is the call graph for this function:

Definition at line 98 of file packer.py.

00098 
00099     def getKeywords(self):
00100         sorted = zip(self.mapping.itervalues(), self.mapping.iterkeys())
00101         sorted.sort()
00102         keywords = []
00103         for (index, encoded), value in sorted:
00104             if index >= 0:
00105                 if encoded != value:
00106                     keywords.append(value)
00107                 else:
00108                     keywords.append('')
00109         return keywords

Here is the caller graph for this function:

Definition at line 110 of file packer.py.

00110 
00111     def sub(self, input):
00112         def repl(m):
00113             return self.mapping.get(m.group(0), ('', m.group(0)))[1]
00114         return self.regexp.sub(repl, input)
00115 

Here is the caller graph for this function:


Member Data Documentation


The documentation for this class was generated from the following file: