@ -303,8 +303,6 @@ _UNARY_OPERATORS_X = (
( ' ! ' , _js_unary_op ( lambda x : _js_ternary ( x , if_true = False , if_false = True ) ) ) ,
( ' ! ' , _js_unary_op ( lambda x : _js_ternary ( x , if_true = False , if_false = True ) ) ) ,
)
)
_OPERATOR_RE = ' | ' . join ( map ( lambda x : re . escape ( x [ 0 ] ) , _OPERATORS + _LOG_OPERATORS ) )
_COMP_OPERATORS = (
_COMP_OPERATORS = (
( ' === ' , _js_id_op ( operator . is_ ) ) ,
( ' === ' , _js_id_op ( operator . is_ ) ) ,
( ' !== ' , _js_id_op ( operator . is_not ) ) ,
( ' !== ' , _js_id_op ( operator . is_not ) ) ,
@ -316,9 +314,12 @@ _COMP_OPERATORS = (
( ' > ' , _js_comp_op ( operator . gt ) ) ,
( ' > ' , _js_comp_op ( operator . gt ) ) ,
)
)
_OPERATOR_RE = ' | ' . join ( map ( lambda x : re . escape ( x [ 0 ] ) , _OPERATORS + _LOG_OPERATORS + _SC_OPERATORS ) )
_NAME_RE = r ' [a-zA-Z_$][ \ w$]* '
_NAME_RE = r ' [a-zA-Z_$][ \ w$]* '
_MATCHING_PARENS = dict ( zip ( * zip ( ' () ' , ' {} ' , ' [] ' ) ) )
_MATCHING_PARENS = dict ( zip ( * zip ( ' () ' , ' {} ' , ' [] ' ) ) )
_QUOTES = ' \' " / '
_QUOTES = ' \' " / '
_NESTED_BRACKETS = r ' [^[ \ ]]+(?: \ [[^[ \ ]]+(?: \ [[^ \ ]]+ \ ])? \ ])? '
class JS_Break ( ExtractorError ) :
class JS_Break ( ExtractorError ) :
@ -1088,15 +1089,18 @@ class JSInterpreter(object):
m = re . match ( r ''' (?x)
m = re . match ( r ''' (?x)
( ? P < assign >
( ? P < assign >
( ? P < out > { _NAME_RE } ) ( ? : \[ ( ? P < out_idx > ( ? : . + ? \] \s * \[ ) * . + ? ) \] ) ? \s *
( ? P < out > { _NAME_RE } ) ( ? P < out_idx > ( ? : \[ { _NESTED_BRACKETS } \] ) + ) ? \s *
( ? P < op > { _OPERATOR_RE } ) ?
( ? P < op > { _OPERATOR_RE } ) ?
= ( ? != ) ( ? P < expr > . * ) $
= ( ? != ) ( ? P < expr > . * ) $
) | ( ? P < return >
) | ( ? P < return >
( ? ! if | return | true | false | null | undefined | NaN | Infinity ) ( ? P < name > { _NAME_RE } ) $
( ? ! if | return | true | false | null | undefined | NaN | Infinity ) ( ? P < name > { _NAME_RE } ) $
) | ( ? P < indexing >
( ? P < in > { _NAME_RE } ) \[ ( ? P < in_idx > ( ? : . + ? \] \s * \[ ) * . + ? ) \] $
) | ( ? P < attribute >
) | ( ? P < attribute >
( ? P < var > { _NAME_RE } ) ( ? : ( ? P < nullish > \? ) ? \. ( ? P < member > [ ^ ( ] + ) | \[ ( ? P < member2 > [ ^ \] ] + ) \] ) \s *
( ? P < var > { _NAME_RE } ) ( ? :
( ? P < nullish > \? ) ? \. ( ? P < member > [ ^ ( ] + ) |
\[ ( ? P < member2 > { _NESTED_BRACKETS } ) \]
) \s *
) | ( ? P < indexing >
( ? P < in > { _NAME_RE } ) ( ? P < in_idx > \[ . + \] ) $
) | ( ? P < function >
) | ( ? P < function >
( ? P < fname > { _NAME_RE } ) \( ( ? P < args > . * ) \) $
( ? P < fname > { _NAME_RE } ) \( ( ? P < args > . * ) \) $
) ''' .format(**globals()), expr)
) ''' .format(**globals()), expr)
@ -1111,10 +1115,11 @@ class JSInterpreter(object):
elif left_val in ( None , JS_Undefined ) :
elif left_val in ( None , JS_Undefined ) :
raise self . Exception ( ' Cannot index undefined variable ' + m . group ( ' out ' ) , expr = expr )
raise self . Exception ( ' Cannot index undefined variable ' + m . group ( ' out ' ) , expr = expr )
indexes = re . split ( r ' \ ] \ s* \ [ ' , m . group ( ' out_idx ' ) )
indexes = md [ ' out_idx ' ]
for i , idx in enumerate ( indexes , 1 ) :
while indexes :
idx , indexes = self . _separate_at_paren ( indexes )
idx = self . interpret_expression ( idx , local_vars , allow_recursion )
idx = self . interpret_expression ( idx , local_vars , allow_recursion )
if i < len ( i ndexes) :
if i ndexes:
left_val = self . _index ( left_val , idx )
left_val = self . _index ( left_val , idx )
if isinstance ( idx , float ) :
if isinstance ( idx , float ) :
idx = int ( idx )
idx = int ( idx )
@ -1159,7 +1164,9 @@ class JSInterpreter(object):
if md . get ( ' indexing ' ) :
if md . get ( ' indexing ' ) :
val = local_vars [ m . group ( ' in ' ) ]
val = local_vars [ m . group ( ' in ' ) ]
for idx in re . split ( r ' \ ] \ s* \ [ ' , m . group ( ' in_idx ' ) ) :
indexes = m . group ( ' in_idx ' )
while indexes :
idx , indexes = self . _separate_at_paren ( indexes )
idx = self . interpret_expression ( idx , local_vars , allow_recursion )
idx = self . interpret_expression ( idx , local_vars , allow_recursion )
val = self . _index ( val , idx )
val = self . _index ( val , idx )
return val , should_return
return val , should_return
@ -1204,7 +1211,7 @@ class JSInterpreter(object):
if obj is JS_Undefined :
if obj is JS_Undefined :
try :
try :
if variable not in self . _objects :
if variable not in self . _objects :
self . _objects [ variable ] = self . extract_object ( variable )
self . _objects [ variable ] = self . extract_object ( variable , local_vars )
obj = self . _objects [ variable ]
obj = self . _objects [ variable ]
except self . Exception :
except self . Exception :
if not nullish :
if not nullish :
@ -1215,7 +1222,7 @@ class JSInterpreter(object):
# Member access
# Member access
if arg_str is None :
if arg_str is None :
return self . _index ( obj , member )
return self . _index ( obj , member , nullish )
# Function call
# Function call
argvals = [
argvals = [
@ -1400,7 +1407,7 @@ class JSInterpreter(object):
for v in self . _separate ( list_txt ) :
for v in self . _separate ( list_txt ) :
yield self . interpret_expression ( v , local_vars , allow_recursion )
yield self . interpret_expression ( v , local_vars , allow_recursion )
def extract_object ( self , objname ):
def extract_object ( self , objname , * global_stack ):
_FUNC_NAME_RE = r ''' (?: {n} | " {n} " | ' {n} ' ) ''' . format ( n = _NAME_RE )
_FUNC_NAME_RE = r ''' (?: {n} | " {n} " | ' {n} ' ) ''' . format ( n = _NAME_RE )
obj = { }
obj = { }
fields = next ( filter ( None , (
fields = next ( filter ( None , (
@ -1421,7 +1428,8 @@ class JSInterpreter(object):
fields ) :
fields ) :
argnames = self . build_arglist ( f . group ( ' args ' ) )
argnames = self . build_arglist ( f . group ( ' args ' ) )
name = remove_quotes ( f . group ( ' key ' ) )
name = remove_quotes ( f . group ( ' key ' ) )
obj [ name ] = function_with_repr ( self . build_function ( argnames , f . group ( ' code ' ) ) , ' F< {0} > ' . format ( name ) )
obj [ name ] = function_with_repr (
self . build_function ( argnames , f . group ( ' code ' ) , * global_stack ) , ' F< {0} > ' . format ( name ) )
return obj
return obj