W3C home > Mailing lists > Public > www-svg@w3.org > March 2010

Re: [Parameters] specifications feedback

From: Domenico Strazzullo <nst@dotuscomus.com>
Date: Tue, 9 Mar 2010 13:54:36 +0100
Message-ID: <6CFF3B8DF4B246D794712788270AE5D1@RAPAX>
To: <www-svg@w3.org>
 Hi,

The SVG Parameters spec seems all good to me. It responds well to the 
declared objectives of "... a declarative way to incorporate... a single 
resource, and reuse it several times with specified variations... without 
the use of script."

Definitions:
type 1 - developers who know how to code and who use code extensively
type 2 - other content authors

As a general rule it is true that the use of params needs to remain simple 
enough and intuitive, however, I think considerable thought should be given 
to the multiple implications, whether immediately apparent or not, as well 
as to those that may result from possible evolutions, so as to avoid the 
risk of generating a cumbersome and obnoxious heritage. Given the stakes, I 
would warmly recommend to let it cook the time that it needs. The design 
should spontaneously result from the evaluation of ALL the implications. The 
many past bruising experiences in several domains of computer and web 
technologies are revelatory and I think it's about time to make that trend a 
thing of the past. At this stage, params seems rather well born. The idea of 
this type of public discussions in symbiosis within a WG seems excellent.

I find the examples talkative and immediately accessible. We need to 
consider that the general public for SVG may grow exponentially -the content 
authors as well as the end users- and this would probably include designers 
and children. The barchart example is very appropriate in that respect. We 
must bear in mind that the objective declared is to address type 2, who have 
been notoriously frustrated with their limitations in respect to scripting. 
While type 1 have always had the means of serializing their objects and 
override properties, type 2 never had them.

4.1 Interface Parameters
The paragraphs marked in yellow.

I have a few questions. Must we always sacrifice to the altar of security? 
For what reasons? On what grounds? Are the risks of the nuclear war type, at 
least? Can we put an end to this excessively zealous prevention plan that 
has already caused too much damage to society? It is the responsibility of a 
bank using SVG content to ensure the correct level of security. Instead of 
preventing I would recommend that incompetent technicians be fired -as 
simple as that- and replaced by qualified engineers, rather than have the 
whole system hijack the population with imaginary security threats. Face it, 
99% of the virus myth came down to be motherboard or other hardware issues, 
while the establishment has had all good -to them- reasons to entertain that 
and other myths. By 99% I mean 99% of the public reactions when facing a 
system malfunction: "I've got a virus". As a good citizen I have the moral 
obligation to fight those who leverage on the latent paranoia of many young 
as well as many among the general population for commercial interests (I 
don't mean by that that those who don't feel they have the same moral 
obligation are not good citizens). SVG does not want to serve the merchants 
of fear. Also, to make an allusion, but by no means in relation to what I 
just said, normally you put a guard outside of a back door, not inside. As 
stupid as it may seem, this thought is worth considering, as to the 
dramatically different implications suggested by the different angles of 
view.

That said, perhaps reasonable compromises can be found?

I would like to stress out that a read-write interface is essential. Not 
implementing such an interface could preclude the eventuality that Params 
will be in effect used by type 1 who are, I suppose, the majority. I believe 
that a read-write interface would unveil tremendous possibilities. If it was 
already available I could use it in a scenario where I had to develop 
another kind of hook, necessarily unofficial.

I can present the scenario.

Please, consider this: over time, type 1 have developed more or less 
efficient programmatic ways to control the appearance and geometry of their 
objects in an industrial environment. The tools at their disposal being 
mainly CSS and/or DOM methods, both having their advantages and limitations, 
but neither allowing total and true OOP. The reproaches that I have to 
formulate in respect to CSS are many -they have been exposed on several 
occasions by others, to which I subscribe- and cover basically its 
limitations. Some DOM methods or properties may be cherished by most type 1, 
including myself, but are nevertheless hacks. CSS, as relating to SVG, is a 
mega hack. But... it has been very useful. Yes, but why? Because a 
Presentation Attributes Sheet type of thing was never designed. This is not 
a criticism, just a simple finding.

During the last two years I set out to rewrite GEMÔ following a class 
inheritance model, and as using an internal library, to make it Open Project 
ready. To conform to the current writing standards I have opted for what is 
known as OOP writing techniques, which I hope some agree is in no way 
sufficient to say that an application uses OOP in effects.

Then, one year ago, I was commissioned to write a SVG controls library, 
which gave me a terrific opportunity to investigate more deeply the matters 
and carry out a diligent and exhaustive study. The results of my research 
confirmed somehow my expectations and intuitions. Moreover, once started 
writing, I realized the invaluable benefits of the crossfire and feedback 
between the sort of Lego box represented by the library and the system 
represented by GEMÔ. Then the question became apparent: can I really, as 
type 1, reach B through A? More precisely, is A capable of supporting the 
systemic intelligence required by B? The answer was: A must be designed so 
that it can support systemic intelligence, fault of which it remains a Lego 
box to play with, like many others.

At that stage I could finally investigate on a concept that I always wanted 
to grasp better, i.e. an object property in javascript can be converted to a 
string, resulting in the common but obscure statement that the "array 
notation" can be used instead of the dot syntax. This is not false but has 
always been put the other way round, presented as secondary, overlooked and 
rarely seen (typing laziness? Negative Java and C++ heritage? Fake 
snobbery?). The reality is very different, a javascript object property can 
be a string OR a js variable/property name, and this gives to javascript way 
much more power that it has generally been admitted, together with the 
possibility of using FP, that Java hasn't.

As a proof of fact I take the param.js script. Doug, you are declaring there 
paramArray as an Array and then right below you use it as what has been 
commonly and wrongly identified on good books as an associative array. This 
is flatly wrong. The associative array, as compared to PHP arrays, is a 
mystification. You are really using an object in a very straightforward 
manner:

var param = {}; // make it top level or namespace protected, not local!
.
param[ name ] = value;

You are declaring an object property name as a string. Licit. param was, is 
and remains an object in its own right.

But more, if and when Params is implemented and hooked, as it should be, 
then name, value and others need to become properties: params[name].value, .

As a sidekick, with an appropriate internal conversion mechanism this could 
be expressed as params.name.value and skip the Frames or Images arrays type 
of idea, although I have no problem with that.

myObject1.x = params[name].value;
myObject2.x = myObject1.x + myObject1.width

I don't mean to say that this needs to resolve (and always supposing that 
myObject1 and myObject2 are direct pointers to objects in the DOM 
tree) -although if it were for me I would contemplate to force this to 
happen (I know, it's a tremendous amount of work)-, we would still 
setAttributeNS() to make it happen.

OK, back to our muttons, as the French say, asking you to be patient as I 
need to go through apparently unrelated subjects before reaching the final 
concept. So there I was, with needs to cope with and no model to follow. I 
set myself to write a pseudo language. I saw all the other libraries that 
have just that. Then I said, hold it, they don't have a library, they're 
dealing with html. All this time we, type 1, like little lambs, have been 
making constructors for primitives and all other elements that existed 
already!! No no no, I have a library (any SVG implementation), I just need 
to ask.

The reasoning:
1) The request mechanism needs to be simply an interface through which type 
1 can pass an object.
2) Nobody needs to know what the properties of this object are or claim to 
be.
3) The library expects to be told by the interface "what" type 1 needs.
4) The library and the interface are not responsible for what is declared, 
just like when type 1 or 2 write plain SVG.
5) The interface only needs to be intelligent enough to give some basic 
instructions to the library.

The deduction: to build an argument object using SVG attribute names for its 
property names, where those names which contain illegal javascript 
characters for variable/property name will be property names in string 
format (which by the way could also be used for any name for consistency); 
to define 1 pseudo-attribute as property name to satisfy point 3 above.

var g = $C({
    element: "g",
    id: this.id + "_spectrumGroup",
    "clip-path": "url(#paletteClip)",
    cursor: "crosshair",
    appendTo: this.group
});

Incidentally, I found useful to create 2 more pseudo-attributes as 
facilities: appendTo, which does what it does, and textNode which can be 
assigned in a text object. They are not mandatory. element is mandatory of 
course.

this.spectrumMask = $C({
    element: "rect",
    width: this.width,
    height: this.height,
    fill: this.fill,
    appendTo: g
});

This is the interface (node builder):

createElement: function(o) {
    for (var p in o) {
        var value = o[p];
        switch(p) {
            case "element" : var element = 
document.createElementNS(gemi.svgNS, value);
            break;
            case "textNode" : 
element.appendChild(document.createTextNode(value));
            break;
            case "appendTo" : value.appendChild(element);
            break;
            default : element.setAttributeNS((p == "xlink:href") ? 
gemi.xlinkNS : null, p, value);
        }
    }
    return element;
},

(This is LGPL and anyone who would like to use it, please, download the file 
from DC with the credits. Thanks)

The call can be volatile, with no reference:

$C({element: "circle", ...attributes...});

Apart from this method, the classes can use a complementary prototype method 
that serves a particular mechanism: the classes only have a relevant set of 
rendering prototype properties; type 1 or another class soliciting an 
instance from said class can of course override the properties but can also 
declare in their argument object any other property, as attribute, that they 
may wish or need, when requesting an instance. This allows the prototype of 
said class to remain free of the overhead burden of carrying any properties 
corresponding to SVG attributes with initial values. As a consequence the 
instances of said class do not redundantly carry (pass) those attributes for 
their elements. Instead, an "extra" object -a prototype property- initially 
empty is queried and anything found in that object is integrated in a 
transient object. Since the constructor, or more precisely one of its 
specialized methods, will not be aware of the meaning or number of such 
extra properties, it passes the transient object to the complementary 
prototype method for compilation:

this.mask = $C(this.attList(element, maskAttributes, this.buttonGroup));

In this way the argument object passed to the interface node builder can be 
compiled by hand or programmatically, and even defined somewhere else in the 
script or in another file.

These methods, combined with the overriding facilities provided by Params 
could expand their scope and become more powerful.

Parallel to this I had a skin engine, and then it was only natural to apply 
the same criteria to it. I set in the skin object a collection of properties 
that would act as selectors, then have the prototype properties of the 
classes point to those selectors. That way I, as well as type 1, would use 
(what I call) the skin as we'd use a style sheet, never needing to go hack 
the classes, with some tremendous advantages:

1) multiple definitions of the same selectors in a single file
2) selectors' properties take references, expressions and functions
3) cross-reference with other classes/selectors
4) access to the namespace object, the superclass and the subclasses (or to 
anything, really)

This is possible because a skin is an object, named 
gemi.presentationAttributes, produced by a method. The method doesn't expect 
parameters and uses properties defined in gemi.settings.public in a config 
file, which then get processed according to cookies contents. At this stage 
it gets a little complicated to expose the mechanism without providing code 
evidence. Here the class selectors get built. They are objects very similar 
to CSS, where the properties have attribute (painting, geometrical, other) 
names as a general rule and may also have pseudo-attributes with names 
arbitrarily set by myself to satisfy the specific needs of the control 
classes (the subclasses). Gradients and patterns also get built here.

Please note that fault of standard I am using a bastard language.

Naturally, if the method producing the current skin could use params to 
retrieve information from, that would be great.

Examples:

    scrollBar: {
        fill: mix([100, 100, 100], 40),
        stroke: "#D0D0D0",
        size: 18,
        type: "linear",
        cradleFill: mix([50, 50, 50], 84),
        horCradleStroke: "url(#hCradleStrokeGrad)",
        vertCradleStroke: "url(#vCradleStrokeGrad)",
        buttonStroke: mix([100, 100, 100], 88)
    },
    scrollSlider: {
        fill: {
            hor: "url(#hScrollSliderGrad)",
            vert: "url(#vScrollSliderGrad)"
        },
        stroke: {
            hor: "url(#hScrollSliderStrokeGrad)",
            vert: "url(#vScrollSliderStrokeGrad)"
        },
        'fill-opacity': .25
    },

* mix is gemi.shadeMix(), an engine producing variations on a theme, capable 
of acting on luminance as well as on hue deviations and saturation.

also:

    frame: {
        fill: mix([90, 90, 90], 24),
        stroke: mix([90, 90, 90], -6),
        rx: 2,
        'fill-opacity': function() {
            var c = gemi.hexToRGB(gemi.background.fill);
            var lum = gemi.luminosity(c[0], c[1], c[2]);
            return (.15 + .15 * (lum < gemi.themeLuminosity));
        },
        'stroke-opacity': function() {
        var c = gemi.hexToRGB(gemi.background.fill);
            var lum = gemi.luminosity(c[0], c[1], c[2]);
            return (.25 + .3 * (lum < gemi.themeLuminosity));
        }
    },


    all: {
        'font-family': "'Segoe UI', 'Trebuchet MS', 'Lucida Grande', 'Deja 
Vu'",
        'font-size': '10pt',
        stroke: "#7F7F7F"
    },

* "all" is an arbitrary name and is pointed at by the superclass prototype.


    background: {
        fill: gemi.settings.public.backgroundColor
    },


    text: {
        fill: (gemi.themeLuminosity < 128)? mix([100, 100, 100], 90) : 
"#000000",
        fillInverse: (gemi.themeLuminosity < 128)? "#000000" : "#FFFFFF",
        shadow: (gemi.themeLuminosity < 128)? "#000000" : mix([82, 84, 
85.5], gemi.themeLuminosity / 4)
    },

* text is not a class, it can be referenced by a property of any class, or 
type 1, who wishes to accord their text element(s) fill to the theme color 
and the luminosity, for example the "title" property referencing the text 
element of a dark top bar would appear in video inverse:

fill: gemi.presentationAttributes.text.fillInverse,

It is evident that the gain would be considerable if the objects or type 1 
didn't need to go through all the hierarchy and bureaucracy to use this 
self-proclaimed Presentation Attributes "sheet".

The two main points that justify this discussion are:
1) To advocate the read-write, always admitting anyway that read-only would 
already provide a lot to play with
2) To advocate the creation of a Presentation Attributes Sheet and to 
establish the communication with Params

Relating to point 2, I would like to say that my solution is embryonic and 
offers what it seems to me a viable mechanism that works anyway like a swiss 
clock in the two applications I've been referring to. Nevertheless, I do 
realize that beyond a certain stage it is not any longer the matter of one 
person; ideas from multiple sources need to converge and situations need to 
be analyzed. Please also note that the skin engine has not yet been released 
as a sort of plugin, snippet or whatever, and neither of the two 
applications mentioned have been released yet.

Regards,
Domenico 
Received on Tuesday, 9 March 2010 12:55:10 GMT

This archive was generated by hypermail 2.3.1 : Friday, 8 March 2013 15:54:44 GMT