Back to index

plone3  3.1.7
Public Member Functions | Public Attributes | Private Member Functions
ResourceRegistries.tools.packer.JavascriptKeywordMapper Class Reference
Inheritance diagram for ResourceRegistries.tools.packer.JavascriptKeywordMapper:
Inheritance graph
[legend]
Collaboration diagram for ResourceRegistries.tools.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 96 of file packer.py.


Constructor & Destructor Documentation

def ResourceRegistries.tools.packer.JavascriptKeywordMapper.__init__ (   self,
  regexp = None,
  encoder = None 
)

Reimplemented from ResourceRegistries.tools.packer.KeywordMapper.

Definition at line 97 of file packer.py.

00097 
00098     def __init__(self, regexp=None, encoder=None):
00099         if regexp is None:
00100             self.regexp = re.compile(r'\w+')
00101         elif isinstance(regexp, (str, unicode)):
00102             self.regexp = re.compile(regexp)
00103         else:
00104             self.regexp = regexp
00105         if encoder is None:
00106             self.encoder = self._encode
00107         else:
00108             self.encoder = encoder
00109         self.mapping = {}


Member Function Documentation

def ResourceRegistries.tools.packer.JavascriptKeywordMapper._encode (   self,
  charCode,
  mapping = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 
) [private]

Definition at line 111 of file packer.py.

00111 
00112                 mapping="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"):
00113         result = []
00114         quotient = charCode
00115         while quotient or not len(result):
00116             quotient, remainder = divmod(quotient, 62)
00117             result.append(mapping[remainder])
00118         result.reverse()
00119         return "".join(result)

def ResourceRegistries.tools.packer.KeywordMapper.analyse (   self,
  input 
) [inherited]

Definition at line 75 of file packer.py.

00075 
00076     def analyse(self, input):
00077         self.mapping = self.analyseKeywords(input)

Here is the call graph for this function:

def ResourceRegistries.tools.packer.KeywordMapper.analyseKeywords (   self,
  input 
) [inherited]

Definition at line 16 of file packer.py.

00016 
00017     def analyseKeywords(self, input):
00018         matches = self.regexp.findall(input)
00019 
00020         protected = {}
00021         keyword_count = {}
00022         index = 0
00023         for match in matches:
00024             if match not in keyword_count:
00025                 keyword_count[match] = 0
00026                 protected[self.encoder(index)] = index
00027                 index = index + 1
00028             keyword_count[match] = keyword_count[match] + 1
00029 
00030         for match in matches:
00031             if match in protected and keyword_count[match]:
00032                 keyword_count[match] = 0
00033 
00034         protected = {}
00035         for match in keyword_count:
00036             if not keyword_count[match]:
00037                 protected[match] = None
00038 
00039         ## sorted_matches = [(c,len(v),v) for v,c in keyword_count.iteritems()]
00040         # the above line implements the original behaviour, the code below
00041         # removes keywords which have not enough weight to be encoded, in total
00042         # this saves some bytes, because the total length of the generated
00043         # codes is a bit smaller. This needs corresponding code in the
00044         # fast_decode javascript function of the decoder, see comment there
00045         sorted_matches = []
00046         for value, count in keyword_count.iteritems():
00047             weight = count * len(value)
00048             if len(value) >= weight:
00049                 keyword_count[value] = 0
00050                 sorted_matches.append((0, value))
00051             else:
00052                 sorted_matches.append((weight, value))
00053         sorted_matches.sort()
00054         sorted_matches.reverse()
00055         sorted_matches = [x[-1] for x in sorted_matches]
00056 
00057         index = 0
00058         mapping = {}
00059         for match in sorted_matches:
00060             if not keyword_count[match]:
00061                 if match not in protected:
00062                     mapping[match] = (-1, match)
00063                 continue
00064             while 1:
00065                 encoded = self.encoder(index)
00066                 index = index + 1
00067                 if encoded in protected:
00068                     mapping[encoded] = (index-1, encoded)
00069                     continue
00070                 else:
00071                     break
00072             mapping[match] = (index-1, encoded)
00073 
00074         return mapping

Here is the caller graph for this function:

def ResourceRegistries.tools.packer.JavascriptKeywordMapper.getDecodeFunction (   self,
  fast = True,
  name = None 
)

Definition at line 120 of file packer.py.

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

Here is the call graph for this function:

Here is the caller graph for this function:

def ResourceRegistries.tools.packer.JavascriptKeywordMapper.getDecoder (   self,
  input,
  keyword_var = None,
  decode_func = None 
)

Definition at line 190 of file packer.py.

00190 
00191     def getDecoder(self, input, keyword_var=None, decode_func=None):
00192         if keyword_var is None:
00193             keywords = self.getKeywords()
00194             num_keywords = len(keywords)
00195             keywords = "|".join(keywords)
00196             keywords = "'%s'.split('|')" % keywords
00197         else:
00198             keywords = keyword_var
00199             num_keywords = len(self.getKeywords())
00200 
00201         if decode_func is None:
00202             decode_func = self.getDecodeFunction()
00203 
00204         escaped_single = input.replace("\\","\\\\").replace("'","\\'").replace('\n','\\n')
00205         escaped_double = input.replace("\\","\\\\").replace('"','\\"').replace('\n','\\n')
00206         if len(escaped_single) < len(escaped_double):
00207             script = "'%s'" % escaped_single
00208         else:
00209             script = '"%s"' % escaped_double
00210         return "eval(%s(%s,62,%i,%s,0,{}))" % (decode_func, script,
00211                                                num_keywords,
00212                                                keywords)
00213 

Here is the call graph for this function:

Definition at line 78 of file packer.py.

00078 
00079     def getKeywords(self):
00080         sorted = zip(self.mapping.itervalues(), self.mapping.iterkeys())
00081         sorted.sort()
00082         keywords = []
00083         for (index, encoded), value in sorted:
00084             if index >= 0:
00085                 if encoded != value:
00086                     keywords.append(value)
00087                 else:
00088                     keywords.append('')
00089         return keywords

Here is the caller graph for this function:

def ResourceRegistries.tools.packer.KeywordMapper.sub (   self,
  input 
) [inherited]

Definition at line 90 of file packer.py.

00090 
00091     def sub(self, input):
00092         def repl(m):
00093             return self.mapping.get(m.group(0), ('', m.group(0)))[1]
00094         return self.regexp.sub(repl, input)
00095 

Here is the caller graph for this function:


Member Data Documentation

Reimplemented from ResourceRegistries.tools.packer.KeywordMapper.

Definition at line 105 of file packer.py.

Reimplemented from ResourceRegistries.tools.packer.KeywordMapper.

Definition at line 108 of file packer.py.

Reimplemented from ResourceRegistries.tools.packer.KeywordMapper.

Definition at line 99 of file packer.py.


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