I'm volunteering some time to work on an open-data project, which I've started a repo out here for:
https://github.com/0xdeadcafe/Open-Hamilton/blob/master/whereare.js
The general idea is you'll paste in script tags the same way Google maps does to any third-party site to call the JavaScript.
I'm trying to prevent global namespace abuses (both-ways), and make configuration very simple and straight-forward.
Right now, the plugin configuration looks like (this is before my re-write):
<script type="text/javascript">
var Config = { height: 500, width: 500 };
document.write(unescape("%3Cscript src='http://example.com/somecode.js' type='text/javascript'%3E%3C/script%3E"));
</script>
I've got a few problems with this, first of all, it's using document.write and hopes that script-tags execute in the way I want them to. I'm scared this will break the page, I'd rather use DOM append child methods.
The other problem here is you can't configure this in-site simply without introducing a global variable.
I'd like to do something where I can call such as:
<script type="text/javascript">
/*document.createelement script tag... make the
src equal to the javascript, pass config data by function parameter?*/);
</script>
So my code is mostly a huge closure, and I try to contain the whole thing inside of there.
(function(conf){
/*things happen*/
})({
"conf": "data",
"etc":"etc"
});
In the code I've linked up above I've made a function confMerge
that attempts to do a recursive deep exclusive replace on the defaults being over-ridden by the configure data. I'm somewhat concerned it's over-kill in a few areas, and may break in others. My other concern is that I can't alter behavior based on type (for instance, google maps API can take a string as a center
parameter, but I provide two numbers, my configure style can't deal with that.)
I've got a few rules, and that's that this needs to be ie6 friendly, I can't play with the prototype to shim ES5 styles, and I can't blow up someone elses website with my plugin, and it needs to be able to work without letting an average website with globals all-over-the-place blow up my widget.
Thoughts?
1 Answer 1
There's nothing stopping you putting a closure in around the script part so you don't have global variables - all except closures cause memory leaks in IE6 - in fact, Google Analytic does it.
The switch statement does look a bit over-kill in confMerge
. I'm not sure typeof will return 'xml'. Most often, all you have to do is options[i] = conf[i] || defaults[i];
, basically. With objects and arrays you just recurse down. I've done this numerous times, so as far as I can see, nothing to worry about.
I don't see why you cannot support strings. You can always build a validator for that specific property.
Update:
I think I realise my mistake. I assumed that copyMerge
did a shallow copy. The way you do it, you enforce the structure of the defaults. I still believe, however, that validation is best solution, but what you should do is a shallow copy, so when you see an object or array you just reference it, rather than calling copyMerge
.
Then to validate the data, I feel that creating validation functions for all the properties is the best way. Thus you can handle the property center
and make sure if it's a string, or an object with the two properties 1 and 0. If it must be an array you can it by using Object.prototype.toString.apply( obj ) === "[object Array]"
.
You can put the validation functions in copyMerge
by creating an object funcs
with the same name as the properties, so object["center"]
or in copyMerge
, object[ i ]
where i === "center"
. Another way is to have a copyMerge
go the copying and have a validator function to validate the data.
-
\$\begingroup\$ The XML is there because that's a possibility in the spec, so I figure'd I account for it somehow. I'm sure I could support strings, my issue is what's an elegant way to actually do that? If my defaults are an array, and I get a string, I don't want to code a one-off setting, I want to design a solution for other things. \$\endgroup\$Incognito– Incognito2011年09月11日 23:02:35 +00:00Commented Sep 11, 2011 at 23:02
-
\$\begingroup\$ I have added more information. A question that cropped up for me is, why do you do a deep copy? \$\endgroup\$NebulaFox– NebulaFox2011年09月12日 10:40:07 +00:00Commented Sep 12, 2011 at 10:40