You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
6.8 KiB
199 lines
6.8 KiB
from ..base import *
|
|
import six
|
|
|
|
#todo Double check everything is OK
|
|
|
|
|
|
@Js
|
|
def Object():
|
|
val = arguments.get('0')
|
|
if val.is_null() or val.is_undefined():
|
|
return PyJsObject(prototype=ObjectPrototype)
|
|
return val.to_object()
|
|
|
|
|
|
@Js
|
|
def object_constructor():
|
|
if len(arguments):
|
|
val = arguments.get('0')
|
|
if val.TYPE == 'Object':
|
|
#Implementation dependent, but my will simply return :)
|
|
return val
|
|
elif val.TYPE in ('Number', 'String', 'Boolean'):
|
|
return val.to_object()
|
|
return PyJsObject(prototype=ObjectPrototype)
|
|
|
|
|
|
Object.create = object_constructor
|
|
Object.own['length']['value'] = Js(1)
|
|
|
|
|
|
class ObjectMethods:
|
|
def getPrototypeOf(obj):
|
|
if not obj.is_object():
|
|
raise MakeError('TypeError',
|
|
'Object.getPrototypeOf called on non-object')
|
|
return null if obj.prototype is None else obj.prototype
|
|
|
|
def getOwnPropertyDescriptor(obj, prop):
|
|
if not obj.is_object():
|
|
raise MakeError(
|
|
'TypeError',
|
|
'Object.getOwnPropertyDescriptor called on non-object')
|
|
return obj.own.get(
|
|
prop.to_string().
|
|
value) # will return undefined if we dont have this prop
|
|
|
|
def getOwnPropertyNames(obj):
|
|
if not obj.is_object():
|
|
raise MakeError(
|
|
'TypeError',
|
|
'Object.getOwnPropertyDescriptor called on non-object')
|
|
return obj.own.keys()
|
|
|
|
def create(obj):
|
|
if not (obj.is_object() or obj.is_null()):
|
|
raise MakeError('TypeError',
|
|
'Object prototype may only be an Object or null')
|
|
temp = PyJsObject(prototype=(None if obj.is_null() else obj))
|
|
if len(arguments) > 1 and not arguments[1].is_undefined():
|
|
if six.PY2:
|
|
ObjectMethods.defineProperties.__func__(temp, arguments[1])
|
|
else:
|
|
ObjectMethods.defineProperties(temp, arguments[1])
|
|
return temp
|
|
|
|
def defineProperty(obj, prop, attrs):
|
|
if not obj.is_object():
|
|
raise MakeError('TypeError',
|
|
'Object.defineProperty called on non-object')
|
|
name = prop.to_string().value
|
|
if not obj.define_own_property(name, ToPropertyDescriptor(attrs)):
|
|
raise MakeError('TypeError', 'Cannot redefine property: %s' % name)
|
|
return obj
|
|
|
|
def defineProperties(obj, properties):
|
|
if not obj.is_object():
|
|
raise MakeError('TypeError',
|
|
'Object.defineProperties called on non-object')
|
|
props = properties.to_object()
|
|
for name in props:
|
|
desc = ToPropertyDescriptor(props.get(name.value))
|
|
if not obj.define_own_property(name.value, desc):
|
|
raise MakeError(
|
|
'TypeError',
|
|
'Failed to define own property: %s' % name.value)
|
|
return obj
|
|
|
|
def seal(obj):
|
|
if not obj.is_object():
|
|
raise MakeError('TypeError', 'Object.seal called on non-object')
|
|
for desc in obj.own.values():
|
|
desc['configurable'] = False
|
|
obj.extensible = False
|
|
return obj
|
|
|
|
def freeze(obj):
|
|
if not obj.is_object():
|
|
raise MakeError('TypeError', 'Object.freeze called on non-object')
|
|
for desc in obj.own.values():
|
|
desc['configurable'] = False
|
|
if is_data_descriptor(desc):
|
|
desc['writable'] = False
|
|
obj.extensible = False
|
|
return obj
|
|
|
|
def preventExtensions(obj):
|
|
if not obj.is_object():
|
|
raise MakeError('TypeError',
|
|
'Object.preventExtensions on non-object')
|
|
obj.extensible = False
|
|
return obj
|
|
|
|
def isSealed(obj):
|
|
if not obj.is_object():
|
|
raise MakeError('TypeError',
|
|
'Object.isSealed called on non-object')
|
|
if obj.extensible:
|
|
return False
|
|
for desc in obj.own.values():
|
|
if desc['configurable']:
|
|
return False
|
|
return True
|
|
|
|
def isFrozen(obj):
|
|
if not obj.is_object():
|
|
raise MakeError('TypeError',
|
|
'Object.isFrozen called on non-object')
|
|
if obj.extensible:
|
|
return False
|
|
for desc in obj.own.values():
|
|
if desc['configurable']:
|
|
return False
|
|
if is_data_descriptor(desc) and desc['writable']:
|
|
return False
|
|
return True
|
|
|
|
def isExtensible(obj):
|
|
if not obj.is_object():
|
|
raise MakeError('TypeError',
|
|
'Object.isExtensible called on non-object')
|
|
return obj.extensible
|
|
|
|
def keys(obj):
|
|
if not obj.is_object():
|
|
raise MakeError('TypeError', 'Object.keys called on non-object')
|
|
return [e for e, d in six.iteritems(obj.own) if d.get('enumerable')]
|
|
|
|
|
|
# add methods attached to Object constructor
|
|
fill_prototype(Object, ObjectMethods, default_attrs)
|
|
# add constructor to prototype
|
|
fill_in_props(ObjectPrototype, {'constructor': Object}, default_attrs)
|
|
# add prototype property to the constructor.
|
|
Object.define_own_property(
|
|
'prototype', {
|
|
'value': ObjectPrototype,
|
|
'enumerable': False,
|
|
'writable': False,
|
|
'configurable': False
|
|
})
|
|
|
|
# some utility functions:
|
|
|
|
|
|
def ToPropertyDescriptor(obj): # page 38 (50 absolute)
|
|
if obj.TYPE != 'Object':
|
|
raise MakeError('TypeError',
|
|
'Can\'t convert non-object to property descriptor')
|
|
desc = {}
|
|
if obj.has_property('enumerable'):
|
|
desc['enumerable'] = obj.get('enumerable').to_boolean().value
|
|
if obj.has_property('configurable'):
|
|
desc['configurable'] = obj.get('configurable').to_boolean().value
|
|
if obj.has_property('value'):
|
|
desc['value'] = obj.get('value')
|
|
if obj.has_property('writable'):
|
|
desc['writable'] = obj.get('writable').to_boolean().value
|
|
if obj.has_property('get'):
|
|
cand = obj.get('get')
|
|
if not (cand.is_undefined() or cand.is_callable()):
|
|
raise MakeError(
|
|
'TypeError',
|
|
'Invalid getter (it has to be a function or undefined)')
|
|
desc['get'] = cand
|
|
if obj.has_property('set'):
|
|
cand = obj.get('set')
|
|
if not (cand.is_undefined() or cand.is_callable()):
|
|
raise MakeError(
|
|
'TypeError',
|
|
'Invalid setter (it has to be a function or undefined)')
|
|
desc['set'] = cand
|
|
if ('get' in desc or 'set' in desc) and ('value' in desc
|
|
or 'writable' in desc):
|
|
raise MakeError(
|
|
'TypeError',
|
|
'Invalid property. A property cannot both have accessors and be writable or have a value.'
|
|
)
|
|
return desc
|