Spaces:
Running
Running
; | |
/* | |
* Copyright (c) 2013-2025 Vanessa Freudenberg | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining a copy | |
* of this software and associated documentation files (the "Software"), to deal | |
* in the Software without restriction, including without limitation the rights | |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
* copies of the Software, and to permit persons to whom the Software is | |
* furnished to do so, subject to the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be included in | |
* all copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
* THE SOFTWARE. | |
*/ | |
// Create Squeak VM namespace | |
if (!self.Squeak) self.Squeak = {}; | |
// Setup a storage for settings | |
if (!Squeak.Settings) { | |
// Try (a working) localStorage and fall back to regular dictionary otherwise | |
var settings; | |
try { | |
// fails in restricted iframe | |
settings = self.localStorage; | |
settings["squeak-foo:"] = "bar"; | |
if (settings["squeak-foo:"] !== "bar") throw Error(); | |
delete settings["squeak-foo:"]; | |
} catch(e) { | |
settings = {}; | |
} | |
Squeak.Settings = settings; | |
} | |
if (!Object.extend) { | |
// Extend object by adding specified properties | |
Object.extend = function(obj /* + more args */ ) { | |
// skip arg 0, copy properties of other args to obj | |
for (var i = 1; i < arguments.length; i++) | |
if (typeof arguments[i] == 'object') | |
for (var name in arguments[i]) | |
obj[name] = arguments[i][name]; | |
}; | |
} | |
// This mimics the Lively Kernel's subclassing scheme. | |
// When running there, Lively's subclasses and modules are used. | |
// Modules serve as namespaces in Lively. SqueakJS uses a flat namespace | |
// named "Squeak", but the code below still supports hierarchical names. | |
if (!Function.prototype.subclass) { | |
// Create subclass using specified class path and given properties | |
Function.prototype.subclass = function(classPath /* + more args */ ) { | |
// create subclass | |
var subclass = function() { | |
if (this.initialize) { | |
var result = this.initialize.apply(this, arguments); | |
if (result !== undefined) return result; | |
} | |
return this; | |
}; | |
// set up prototype | |
var protoclass = function() { }; | |
protoclass.prototype = this.prototype; | |
subclass.prototype = new protoclass(); | |
// skip arg 0, copy properties of other args to prototype | |
for (var i = 1; i < arguments.length; i++) | |
Object.extend(subclass.prototype, arguments[i]); | |
// add class to namespace | |
var path = classPath.split("."), | |
className = path.pop(), | |
// Walk path starting at the global namespace (self) | |
// creating intermediate namespaces if necessary | |
namespace = path.reduce(function(namespace, path) { | |
if (!namespace[path]) namespace[path] = {}; | |
return namespace[path]; | |
}, self); | |
namespace[className] = subclass; | |
return subclass; | |
}; | |
} | |