[TIMOB-18465] Globals are not (over)writable
GitHub Issue | n/a |
---|---|
Type | Improvement |
Priority | None |
Status | Open |
Resolution | Unresolved |
Affected Version/s | Release 3.5.0 |
Fix Version/s | n/a |
Components | iOS |
Labels | ios-jscore, kroll, parity |
Reporter | Pier Paolo Ramon |
Assignee | Christopher Williams |
Created | 2015-01-29T09:26:28.000+0000 |
Updated | 2019-04-26T19:04:21.000+0000 |
Description
Currently globals are not set with the ‘right’ flags. We cannot actually say right or wrong flags, because they’re not in the EcmaScript definition.
Some discussion happened on https://github.com/smclab/titaniumifier/issues/31.
The code to test the descriptors is the following:
var global = (function () { return this; }());
if ((typeof window !== 'undefined') &&
(window === global) &&
(!window.hasOwnProperty('alert'))) {
// In the browser the globals are not directly in the window, but in the
// prototype chain
global = Object.getPrototypeOf(global);
}
printPropertyDescriptor(global, 'alert');
printPropertyDescriptor(global, 'setTimeout');
printPropertyDescriptor(global, 'clearTimeout');
printPropertyDescriptor(global, 'setInterval');
printPropertyDescriptor(global, 'clearInterval');
function printPropertyDescriptor(obj, name) {
var descriptor = Object.getOwnPropertyDescriptor(obj, 'clearTimeout');
var formatted = JSON.stringify(descriptor, null, 2);
console.log(name + " = " + formatted);
}
The result is different in every environment. As you will see only Titanium *on iOS* is setting the properties as non-writable.
Also, if using "use strict"
trying to overwrite those properties will result in an error thrown.
*Node.js*
alert = {
"writable": true,
"enumerable": true,
"configurable": true
}
setTimeout = {
"writable": true,
"enumerable": true,
"configurable": true
}
clearTimeout = {
"writable": true,
"enumerable": true,
"configurable": true
}
setInterval = {
"writable": true,
"enumerable": true,
"configurable": true
}
clearInterval = {
"writable": true,
"enumerable": true,
"configurable": true
}
*Chrome*
alert = {
"writable": true,
"enumerable": true,
"configurable": false
}
setTimeout = {
"writable": true,
"enumerable": true,
"configurable": false
}
clearTimeout = {
"writable": true,
"enumerable": true,
"configurable": false
}
setInterval = {
"writable": true,
"enumerable": true,
"configurable": false
}
clearInterval = {
"writable": true,
"enumerable": true,
"configurable": false
}
*Firefox*
alert = {
"configurable": true,
"enumerable": true,
"writable": true
}
setTimeout = {
"configurable": true,
"enumerable": true,
"writable": true
}
clearTimeout = {
"configurable": true,
"enumerable": true,
"writable": true
}
setInterval = {
"configurable": true,
"enumerable": true,
"writable": true
}
clearInterval = {
"configurable": true,
"enumerable": true,
"writable": true
}
*Titanium Android*
alert = {
"writable": true,
"enumerable": true,
"configurable": true
}
setTimeout = {
"writable": true,
"enumerable": true,
"configurable": true
}
clearTimeout = {
"writable": true,
"enumerable": true,
"configurable": true
}
setInterval = {
"writable": true,
"enumerable": true,
"configurable": true
}
clearInterval = {
"writable": true,
"enumerable": true,
"configurable": true
}
*Titanium iOS* (drumroll)
alert = {
"writable": false,
"enumerable": true,
"configurable": false
}
setTimeout = {
"writable": false,
"enumerable": true,
"configurable": false
}
clearTimeout = {
"writable": false,
"enumerable": true,
"configurable": false
}
setInterval = {
"writable": false,
"enumerable": true,
"configurable": false
}
clearInterval = {
"writable": false,
"enumerable": true,
"configurable": false
}
Here’s the culprit: https://github.com/appcelerator/titanium_mobile/blob/2c7f6fb74fa772e1ecc8d9d5209f83c4a0c06aab/iphone/Classes/KrollContext.m#L1112 Why are them explicitly set as
kTiPropertyAttributeReadOnly | kTiPropertyAttributeDontDelete
? There’s no (real) reason for doing this…