Re: [whatwg] script features

2012-03-25 Thread Jonas Sicking
On Fri, Mar 23, 2012 at 9:41 PM, Ian Hickson i...@hixie.ch wrote:
 On Fri, 23 Mar 2012, Jonas Sicking wrote:

 The whole point of this feature is to enable the js-code inside a loaded
 script to use the .currentScript property in order to find the script
 element in the DOM which loaded it.

 Ah, ok. What's the use case for that?

One use case is to be able to pass parameters to a script library by
sticking the information in the markup. data-* attributes would work
great for this. I seem to recall jQuery doing something like this, but
can't find information about that right now.

In the case of ReSpec it uses it to get its own url and then use that
as a base url to load dependent scripts as needed.

/ Jonas


Re: [whatwg] script features

2012-03-24 Thread Kornel Lesiński

On Sat, 24 Mar 2012 04:41:38 -, Ian Hickson i...@hixie.ch wrote:


The whole point of this feature is to enable the js-code inside a loaded
script to use the .currentScript property in order to find the script
element in the DOM which loaded it.


Ah, ok. What's the use case for that?


Embedding of 3rd party widgets asynchronously:

script async src=3rd-party-widget.js/script

Then the script could find its node in the document and replace it with  
whatever it wants.



Another use case would be a (superficial) emulation of document.write()  
for scripts that have been embedded asynchronously.


--
regards, Kornel Lesiński


Re: [whatwg] script features

2012-03-23 Thread Jonas Sicking
On Fri, Feb 3, 2012 at 10:34 PM, Ian Hickson i...@hixie.ch wrote:

 On Mon, 16 Aug 2010, Jonas Sicking wrote:

 I'd like to propose a couple of simple features to make script
 elements more useful:

 1. document.currentScript

 This property returns the currently executing script, if any. Returns
 null if no script is currently executing. In the case of several
 nested executing scripts, it returns the innermost one. This is useful
 for being able to pass parameters to the script by setting data-
 attributes on the script element.

 I think jQuery already does things that requires knowing which script
 element linked to jQuery, and it approximates this property by getting
 the last element in document.getElementsByTagName(script), which won't
 work reliably. Especially with features like script async.

 This feature is trivially implementable using the next one, so I haven't
 added it.

The whole point of this feature is to enable the js-code inside a
loaded script to use the .currentScript property in order to find the
script element in the DOM which loaded it. While it is trivial to
implement the .currentScript property from outside of the script
element, it is impossible to do so from inside the loaded script
itself. This since the script runs after the fired event.

I just ran into another example of a script which tries to figure out
which script element loaded it. In this case it does so by checking
which script element has a src attribute which contains the url it
expects to be loaded from. This causes it to fail when I load the
script from another url. In this case it was the respec.js script
available here: http://dev.w3.org/2009/dap/ReSpec.js/js/respec.js

So yes, it's trivial for pages to implement this. But it mostly
defeats the purpose if every page which wants to use a given library
has to re-implement this property. And it likely will mean that script
libraries won't be able to depend on the property since pages won't
implement it reliably enough.

/ Jonas


Re: [whatwg] script features

2012-03-23 Thread Ian Hickson
On Fri, 23 Mar 2012, Jonas Sicking wrote:
 
 The whole point of this feature is to enable the js-code inside a loaded 
 script to use the .currentScript property in order to find the script 
 element in the DOM which loaded it.

Ah, ok. What's the use case for that?

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] script features

2010-08-24 Thread Henri Sivonen
On Aug 17, 2010, at 07:15, Jonas Sicking wrote:

 These events fire right before and right after a script is executed.
 This allows a page to override the context a specific script is
 seeing.

The relative order with onload should be documented.

 (I've written an implementation for firefox for these features here:
 https://bugzilla.mozilla.org/show_bug.cgi?id=587931)

By looking at the patch, it seems that insertion the events fire before 
document.write() becomes permitted (if applicable) and after it becomes 
forbidden again. Whether the handlers for these events should be able to call 
document.write() without blowing away has a dependency on the resolution of 
http://www.w3.org/Bugs/Public/show_bug.cgi?id=9984 and the relative order of 
the new events and onload.

-- 
Henri Sivonen
hsivo...@iki.fi
http://hsivonen.iki.fi/




Re: [whatwg] script features

2010-08-18 Thread Jonas Sicking
On Tue, Aug 17, 2010 at 9:45 PM, John J. Barton
johnjbar...@johnjbarton.com wrote:
 (though I'm not sure which environment is compiled in other than
 the global object, which you can't replace anyway, at least not for
 now).


 Well if I intercept the event and change the source to
   with(browserShim) {
      ... script tag contents here
   }
 Then I compile into another environment. Otherwise how can I achieve your
 goal?

 These events in and of themselves doesn't allow you to modify the
 script source. This does seem like a neat idea, if you have ideas for
 how this would be done please do suggest them here.

 For example,
 myWillExecuteHandler = function(event)
 {
    var elt = event.target;
    var adulterate = with(shim){\n+elt.innerHTML+}\n;
    eval(adulterate);
    return false; // need some way to abort the script tag in progress.
 }

This doesn't work for external scripts. I.e. ones with a src attribute.

 What I was thinking was simply allowing the event handler to do things
 like:

 var oldWrite;
 myWillExecuteHandler(event) {
   oldWrite = document.write;
   document.write = myWriteOverride;
 }
 myDidExecuteHandler(event) {
   document.write = oldWrite;
 }

 But I guess you don't need events to modify and restore the environment, why
 not just put a script before and after:
 script
 oldWrite = document.write;
 document.write = function(msg) { console.log(msg); }
 /script
 script
 document.write(I command you!);
 /script
 script
 document.write = oldWrite;
 /script

This doesn't work if the script whose evironment you want to modify is
an asynchronous script. It also is significantly more cumbersome,
especially if you want to do this to several script elements in your
page. It also doesn't work if some parts of your markup is generated
by other libraries or components that you don't directly control,
which is exactly the situation when you generally want to use shims.

 If this kind of event were provided for all compilations, Javascript
 debugging would make a quantum leap forward in performance and
 reliability.
 Firebug, for example, uses egregious hacks to fake these events on the
 mozilla platform.


 This feature is not enough for that. For example this event is not
 fired for onXXX event handlers, calls to eval(), calls to the Function
 constructor, calls to WorkerGlobalScope.importScripts or loading of
 Workers and SharedWorkers.


 But if you don't cover these paths then I don't think the feature is
 complete, because what ever developers do in top-level functions of
 script
 tag source they do in all those other cases too.

 It's not intended for implementing debuggers. I suspect a debugging
 API would require something significantly more complex in order to
 deal with all the features I listed. For one, how would you deal with
 the fact that workers can cause scripts to compile and evaluate on
 multiple threads?

 Again, its not a debugging API, it's just the same API you propose.  If
 workers cause scripts to compile, and it triggers event handlers they run on
 the worker thread (and consequently cannot operate on the UI).  And if you
 want to talk about complex, let's talk about what developers have to do now
 or what debugger have to do to try to help them.

I'm all for improving debuggers. However I don't see a need to expose
the APIs that debuggers need to web pages. If there are features that
web pages need, and that debuggers happen to be able to use, then
that's great. But features should be added based on if web pages need
them, not if debuggers or implementations need them internally.

/ Jonas


Re: [whatwg] script features

2010-08-18 Thread John J. Barton

 On 8/17/2010 11:52 PM, Jonas Sicking wrote:

On Tue, Aug 17, 2010 at 9:45 PM, John J. Barton
johnjbar...@johnjbarton.com  wrote:

(though I'm not sure which environment is compiled in other than
the global object, which you can't replace anyway, at least not for
now).


Well if I intercept the event and change the source to
   with(browserShim) {
  ... script tag contents here
   }
Then I compile into another environment. Otherwise how can I achieve your
goal?

These events in and of themselves doesn't allow you to modify the
script source. This does seem like a neat idea, if you have ideas for
how this would be done please do suggest them here.

For example,
myWillExecuteHandler = function(event)
{
var elt = event.target;
var adulterate = with(shim){\n+elt.innerHTML+}\n;
eval(adulterate);
return false; // need some way to abort the script tag in progress.
}

This doesn't work for external scripts. I.e. ones with a src attribute.
I think is it appropriate for the proposed event to have a property 
pointing to the source.

What I was thinking was simply allowing the event handler to do things
like:

var oldWrite;
myWillExecuteHandler(event) {
   oldWrite = document.write;
   document.write = myWriteOverride;
}
myDidExecuteHandler(event) {
   document.write = oldWrite;
}

But I guess you don't need events to modify and restore the environment, why
not just put a script before and after:
script
oldWrite = document.write;
document.write = function(msg) { console.log(msg); }
/script
script
document.write(I command you!);
/script
script
document.write = oldWrite;
/script

This doesn't work if the script whose evironment you want to modify is
an asynchronous script. It also is significantly more cumbersome,
Similarly script tag event approach only works in async cases which 
rely on script tags; it won't work if the async is caused by eg window 
load event handlers or setTimeouts.  The proposal offers only partial 
support for intercepting Javascript before compilation, I think it 
should offer complete support.



especially if you want to do this to severalscript  elements in your
page. It also doesn't work if some parts of your markup is generated
by other libraries or components that you don't directly control,
which is exactly the situation when you generally want to use shims.
I don't understand this. The script tag event fires and runs code 
before and after the script tag content is compiled and the top level 
function runs. The above example runs code before and after the script 
tag content is compiled and the top-level function runs. How can one not 
get the same answer? I suppose the body of the target script tag could 
prevent the trailing script from running, but it could also prevent the 
event handler.


jjb


Re: [whatwg] script features

2010-08-18 Thread Jonas Sicking
On Tue, Aug 17, 2010 at 10:39 PM, John J. Barton
johnjbar...@johnjbarton.com wrote:
  On 8/17/2010 11:52 PM, Jonas Sicking wrote:

 On Tue, Aug 17, 2010 at 9:45 PM, John J. Barton
 johnjbar...@johnjbarton.com  wrote:

 (though I'm not sure which environment is compiled in other than
 the global object, which you can't replace anyway, at least not for
 now).


 Well if I intercept the event and change the source to
   with(browserShim) {
      ... script tag contents here
   }
 Then I compile into another environment. Otherwise how can I achieve
 your
 goal?

 These events in and of themselves doesn't allow you to modify the
 script source. This does seem like a neat idea, if you have ideas for
 how this would be done please do suggest them here.

 For example,
 myWillExecuteHandler = function(event)
 {
    var elt = event.target;
    var adulterate = with(shim){\n+elt.innerHTML+}\n;
    eval(adulterate);
    return false; // need some way to abort the script tag in progress.
 }

 This doesn't work for external scripts. I.e. ones with a src attribute.

 I think is it appropriate for the proposed event to have a property pointing
 to the source.

I'll have to think about it, might not be a bad idea. Curious to get
input from others here.

 What I was thinking was simply allowing the event handler to do things
 like:

 var oldWrite;
 myWillExecuteHandler(event) {
   oldWrite = document.write;
   document.write = myWriteOverride;
 }
 myDidExecuteHandler(event) {
   document.write = oldWrite;
 }

 But I guess you don't need events to modify and restore the environment,
 why
 not just put a script before and after:
 script
 oldWrite = document.write;
 document.write = function(msg) { console.log(msg); }
 /script
 script
 document.write(I command you!);
 /script
 script
 document.write = oldWrite;
 /script

 This doesn't work if the script whose evironment you want to modify is
 an asynchronous script. It also is significantly more cumbersome,

 Similarly script tag event approach only works in async cases which rely
 on script tags; it won't work if the async is caused by eg window load
 event handlers or setTimeouts.  The proposal offers only partial support for
 intercepting Javascript before compilation, I think it should offer complete
 support.

It's not a proposal for intercepting all script compilation. It's a
bit unclear to me what the use case for a webpage to intercept all
compilation is? It also seems significantly more complex in the face
of things like workers and language features like eval and setTimeout.

The use case here is being able to intercept the execution when
linking to a particular library. I could also see wanting to intercept
the compilation and initial execution of on* attributes as that would
allow you to intercept all execution that happens in a particular
subtree. This is useful if you get a chunk of HTML, rather than simply
a script url, from an external source.

 especially if you want to do this to severalscript  elements in your
 page. It also doesn't work if some parts of your markup is generated
 by other libraries or components that you don't directly control,
 which is exactly the situation when you generally want to use shims.

 I don't understand this. The script tag event fires and runs code before
 and after the script tag content is compiled and the top level function
 runs. The above example runs code before and after the script tag content is
 compiled and the top-level function runs. How can one not get the same
 answer? I suppose the body of the target script tag could prevent the
 trailing script from running, but it could also prevent the event handler.

Your solution requires modifying the HTML markup. My solution only
requires attaching an event handler to the document node. The former
isn't always possible, and the latter is almost always significantly
easier.

/ Jonas


Re: [whatwg] script features

2010-08-17 Thread Giorgio Maone

 They would be great additions, thanks.


2. scriptwillexecute/scriptdidexecute events
Notice that Opera has a richer set of eventsof this kind (exsposed to 
privileged User Scripts, though, AFAIK), allowing for much more control over 
the executing scripts, no matter if from script elements, event handlers or URLs:

http://www.opera.com/docs/userjs/specs/#evlistener

Cheers
-- G

Jonas Sicking wrote, On 17/08/2010 6.15:

Hi All,

I'd like to propose a couple of simple features to makescript
elements more useful:

1. document.currentScript

This property returns the currently executingscript, if any.
Returns null if noscript  is currently executing. In the case of
several nested executingscripts, it returns the innermost one. This
is useful for being able to pass parameters to the script by setting
data- attributes on the script element.

I think jQuery already does things that requires knowing which
script  element linked to jQuery, and it approximates this property
by getting the last element in
document.getElementsByTagName(script), which won't work reliably.
Especially with features likescript async.

2. scriptwillexecute/scriptdidexecute events

These events fire right before and right after ascript  is executed.
This allows a page to override the context a specific script is
seeing. For example installing compatibility shims for older browsers.
Another possible use for this is to make ads execute asynchronously.
Currently this is problematic because a lot of ads use document.write
and so the content will be lost (or worse) if an async attribute is
added to thescript  element used to load the ad. Using these events
a page can override document.write while a specific script is
executing and insert the written content into the DOM.

(I've written an implementation for firefox for these features here:
https://bugzilla.mozilla.org/show_bug.cgi?id=587931)

/ Jonas




Re: [whatwg] script features

2010-08-17 Thread Nicholas Zakas
Really like the idea, though I think the naming of Opera's events 
(beforescript, afterscript) fit in better with other events on the page 
(i.e. beforeunload).

-Nicholas
 
__
Commander Lock: Dammit Morpheus, not everyone believes what you believe!
Morpheus: My beliefs do not require them to.

-Original Message-
From: whatwg-boun...@lists.whatwg.org [mailto:whatwg-boun...@lists.whatwg.org] 
On Behalf Of Giorgio Maone
Sent: Monday, August 16, 2010 11:12 PM
To: Jonas Sicking
Cc: WHAT Working Group
Subject: Re: [whatwg] script features

  They would be great additions, thanks.

 2. scriptwillexecute/scriptdidexecute events
Notice that Opera has a richer set of eventsof this kind (exsposed to 
privileged User Scripts, though, AFAIK), allowing for much more control over 
the executing scripts, no matter if from script elements, event handlers or 
URLs:
http://www.opera.com/docs/userjs/specs/#evlistener

Cheers
-- G

Jonas Sicking wrote, On 17/08/2010 6.15:
 Hi All,

 I'd like to propose a couple of simple features to makescript
 elements more useful:

 1. document.currentScript

 This property returns the currently executingscript, if any.
 Returns null if noscript  is currently executing. In the case of
 several nested executingscripts, it returns the innermost one. This
 is useful for being able to pass parameters to the script by setting
 data- attributes on the script element.

 I think jQuery already does things that requires knowing which
 script  element linked to jQuery, and it approximates this property
 by getting the last element in
 document.getElementsByTagName(script), which won't work reliably.
 Especially with features likescript async.

 2. scriptwillexecute/scriptdidexecute events

 These events fire right before and right after ascript  is executed.
 This allows a page to override the context a specific script is
 seeing. For example installing compatibility shims for older browsers.
 Another possible use for this is to make ads execute asynchronously.
 Currently this is problematic because a lot of ads use document.write
 and so the content will be lost (or worse) if an async attribute is
 added to thescript  element used to load the ad. Using these events
 a page can override document.write while a specific script is
 executing and insert the written content into the DOM.

 (I've written an implementation for firefox for these features here:
 https://bugzilla.mozilla.org/show_bug.cgi?id=587931)

 / Jonas



Re: [whatwg] script features

2010-08-17 Thread John J Barton

whatwg-requ...@lists.whatwg.org wrote:

Date: Mon, 16 Aug 2010 21:15:35 -0700
From: Jonas Sicking jo...@sicking.cc
To: WHAT Working Group wha...@whatwg.org
Subject: [whatwg] script features
Message-ID:
aanlktin3t5zb4druxj8ws_hiusgs3pmozl8wogrtc...@mail.gmail.com
Content-Type: text/plain; charset=ISO-8859-1

Hi All,

I'd like to propose a couple of simple features to make script
elements more useful:

1. document.currentScript

This property returns the currently executing script, if any.
Returns null if no script is currently executing. In the case of
several nested executing scripts, it returns the innermost one. This
is useful for being able to pass parameters to the script by setting
data- attributes on the script element.
  
I wonder if you mean: This property returns the script tag defining 
the currently executing top-level function?

So for:
script
var foo = function() {
alert(a foo);
}
foo();
window.addEventListener(load, foo, false);
/script
the property will be null until the script tag is parsed and passed to 
the compiler. Then the property will point to the script tag during the 
execution of the outer or top level function which defines foo, calls 
foo, and sets foo as a load handler. Then the property is null again. 
When the load event runs, the property is null.



I think jQuery already does things that requires knowing which
script element linked to jQuery, and it approximates this property
by getting the last element in
document.getElementsByTagName(script), which won't work reliably.
Especially with features like script async.

2. scriptwillexecute/scriptdidexecute events

These events fire right before and right after a script is executed.
This allows a page to override the context a specific script is
seeing. For example installing compatibility shims for older browsers.
  
But by the time the functions execute, the environment of compilation 
has already been bound into the functions. I think you want the event 
*before* compilation.


If this kind of event were provided for all compilations, Javascript 
debugging would make a quantum leap forward in performance and 
reliability. Firebug, for example, uses egregious hacks to fake these 
events on the mozilla platform.


jjb


Re: [whatwg] script features

2010-08-17 Thread Jonas Sicking
On Tue, Aug 17, 2010 at 2:17 PM, John J Barton
johnjbar...@johnjbarton.com wrote:
 whatwg-requ...@lists.whatwg.org wrote:

 Date: Mon, 16 Aug 2010 21:15:35 -0700
 From: Jonas Sicking jo...@sicking.cc
 To: WHAT Working Group wha...@whatwg.org
 Subject: [whatwg] script features
 Message-ID:
        aanlktin3t5zb4druxj8ws_hiusgs3pmozl8wogrtc...@mail.gmail.com
 Content-Type: text/plain; charset=ISO-8859-1

 Hi All,

 I'd like to propose a couple of simple features to make script
 elements more useful:

 1. document.currentScript

 This property returns the currently executing script, if any.
 Returns null if no script is currently executing. In the case of
 several nested executing scripts, it returns the innermost one. This
 is useful for being able to pass parameters to the script by setting
 data- attributes on the script element.


 I wonder if you mean: This property returns the script tag defining the
 currently executing top-level function?
 So for:
 script
 var foo = function() {
 alert(a foo);
 }
 foo();
 window.addEventListener(load, foo, false);
 /script
 the property will be null until the script tag is parsed and passed to the
 compiler. Then the property will point to the script tag during the
 execution of the outer or top level function which defines foo, calls foo,
 and sets foo as a load handler. Then the property is null again. When the
 load event runs, the property is null.

That is correct. Though it's not related to if the script is top-level
or not. It's simply related to *when* the script statements execute.
The definition would likely be integrated in the steps related to
processing of script elements.

 I think jQuery already does things that requires knowing which
 script element linked to jQuery, and it approximates this property
 by getting the last element in
 document.getElementsByTagName(script), which won't work reliably.
 Especially with features like script async.

 2. scriptwillexecute/scriptdidexecute events

 These events fire right before and right after a script is executed.
 This allows a page to override the context a specific script is
 seeing. For example installing compatibility shims for older browsers.


 But by the time the functions execute, the environment of compilation has
 already been bound into the functions. I think you want the event *before*
 compilation.

Sure (though I'm not sure which environment is compiled in other than
the global object, which you can't replace anyway, at least not for
now).

 If this kind of event were provided for all compilations, Javascript
 debugging would make a quantum leap forward in performance and reliability.
 Firebug, for example, uses egregious hacks to fake these events on the
 mozilla platform.

This feature is not enough for that. For example this event is not
fired for onXXX event handlers, calls to eval(), calls to the Function
constructor, calls to WorkerGlobalScope.importScripts or loading of
Workers and SharedWorkers.

For debugging APIs I suggest platform specific notification mechanisms
as they are much more performant and easier to implement.

/ Jonas


Re: [whatwg] script features

2010-08-17 Thread John J Barton




Jonas Sicking wrote:

  On Tue, Aug 17, 2010 at 2:17 PM, John J Barton
johnjbar...@johnjbarton.com wrote:
  
  
whatwg-requ...@lists.whatwg.org wrote:


  Date: Mon, 16 Aug 2010 21:15:35 -0700
From: Jonas Sicking jo...@sicking.cc
To: WHAT Working Group wha...@whatwg.org
Subject: [whatwg] script features
Message-ID:
   aanlktin3t5zb4druxj8ws_hiusgs3pmozl8wogrtc...@mail.gmail.com
Content-Type: text/plain; charset=ISO-8859-1

Hi All,

I'd like to propose a couple of simple features to make script
elements more useful:

1. document.currentScript

This property returns the currently executing script, if any.
Returns null if no script is currently executing. In the case of
several nested executing scripts, it returns the innermost one. This
is useful for being able to pass parameters to the script by setting
data- attributes on the script element.

  

I wonder if you mean: "This property returns the script tag defining the
currently executing top-level function"?
So for:
script
var foo = function() {
alert("a foo");
}
foo();
window.addEventListener("load", foo, false);
/script
the property will be null until the script tag is parsed and passed to the
compiler. Then the property will point to the script tag during the
execution of the outer or top level function which defines foo, calls foo,
and sets foo as a load handler. Then the property is null again. When the
load event runs, the property is null.

  
  
That is correct. 

Well either this is correct *or* you fire the event before compiling
(see below). I think my description is not correct, and that's good.

  Though it's not related to if the script is top-level
or not. It's simply related to *when* the script statements execute.
  

(It's the function that is top-level.)

I guess you mean by "execute the script", "compile the source
in the tag and run the top-level function"?


...
  

  
seeing. For example installing compatibility shims for older browsers.

  

But by the time the functions execute, the environment of compilation has
already been bound into the functions. I think you want the event *before*
compilation.

  
  
Sure 

Ok, so before compilation and hence my description above is *not*
correct. Good.

  (though I'm not sure which environment is compiled in other than
the global object, which you can't replace anyway, at least not for
now).
  

Well if I intercept the event and change the source to 
 with(browserShim) {
 ... script tag contents here
 }
Then I compile into another environment. Otherwise how can I achieve
your goal?

  
  
  
If this kind of event were provided for all compilations, _javascript_
debugging would make a quantum leap forward in performance and reliability.
Firebug, for example, uses egregious hacks to fake these events on the
mozilla platform.

  
  
This feature is not enough for that. For example this event is not
fired for onXXX event handlers, calls to eval(), calls to the Function
constructor, calls to WorkerGlobalScope.importScripts or loading of
Workers and SharedWorkers.
  

But if you don't cover these paths then I don't think the feature is
complete, because what ever developers do in top-level functions of
script tag source they do in all those other cases too.

  
For debugging APIs I suggest platform specific notification mechanisms
as they are much more performant and easier to implement.
  

Well I was just suggesting another use case for your suggested feature.
You are suggesting an introspection feature that also has potential for
debugging. Web debuggers are mostly based on introspection APIs, a
notable exception being _javascript_ control. Your feature would be good
step in that direction.
jjb

  
/ Jonas
  






Re: [whatwg] script features

2010-08-17 Thread Jonas Sicking
On Tue, Aug 17, 2010 at 6:14 PM, John J Barton
johnjbar...@johnjbarton.com wrote:
 Jonas Sicking wrote:

 On Tue, Aug 17, 2010 at 2:17 PM, John J Barton
 johnjbar...@johnjbarton.com wrote:


 whatwg-requ...@lists.whatwg.org wrote:


 Date: Mon, 16 Aug 2010 21:15:35 -0700
 From: Jonas Sicking jo...@sicking.cc
 To: WHAT Working Group wha...@whatwg.org
 Subject: [whatwg] script features
 Message-ID:
        aanlktin3t5zb4druxj8ws_hiusgs3pmozl8wogrtc...@mail.gmail.com
 Content-Type: text/plain; charset=ISO-8859-1

 Hi All,

 I'd like to propose a couple of simple features to make script
 elements more useful:

 1. document.currentScript

 This property returns the currently executing script, if any.
 Returns null if no script is currently executing. In the case of
 several nested executing scripts, it returns the innermost one. This
 is useful for being able to pass parameters to the script by setting
 data- attributes on the script element.



 I wonder if you mean: This property returns the script tag defining the
 currently executing top-level function?
 So for:
 script
 var foo = function() {
 alert(a foo);
 }
 foo();
 window.addEventListener(load, foo, false);
 /script
 the property will be null until the script tag is parsed and passed to the
 compiler. Then the property will point to the script tag during the
 execution of the outer or top level function which defines foo, calls foo,
 and sets foo as a load handler. Then the property is null again. When the
 load event runs, the property is null.


 That is correct.

 Well either this is correct *or* you fire the event before compiling (see
 below). I think my description is not correct, and that's good.

I'm not sure which event you are referring to here?

 Though it's not related to if the script is top-level
 or not. It's simply related to *when* the script statements execute.

 (It's the function that is top-level.)

 I guess you mean by execute the script, compile the source in the tag
 and run the top-level function?

To get to specification level detail, I mean:

In the If the load was successful algorithm at [1], insert a step
before the current step 3 which says:

Set the documents /current-script/ to the script element node.

And insert a step after the current step 3 which says:

Set the documents /current-script/ to the value it had before it was
modified above.

And define a currentScript IDL attribute on Document which returns the
documents /current-script/ property.

[1] http://www.whatwg.org/specs/web-apps/current-work/#executing-a-script-block

 (though I'm not sure which environment is compiled in other than
 the global object, which you can't replace anyway, at least not for
 now).


 Well if I intercept the event and change the source to
   with(browserShim) {
  ... script tag contents here
   }
 Then I compile into another environment. Otherwise how can I achieve your
 goal?

These events in and of themselves doesn't allow you to modify the
script source. This does seem like a neat idea, if you have ideas for
how this would be done please do suggest them here.

What I was thinking was simply allowing the event handler to do things like:

var oldWrite;
myWillExecuteHandler(event) {
  oldWrite = document.write;
  document.write = myWriteOverride;
}
myDidExecuteHandler(event) {
  document.write = oldWrite;
}

 If this kind of event were provided for all compilations, Javascript
 debugging would make a quantum leap forward in performance and reliability.
 Firebug, for example, uses egregious hacks to fake these events on the
 mozilla platform.


 This feature is not enough for that. For example this event is not
 fired for onXXX event handlers, calls to eval(), calls to the Function
 constructor, calls to WorkerGlobalScope.importScripts or loading of
 Workers and SharedWorkers.


 But if you don't cover these paths then I don't think the feature is
 complete, because what ever developers do in top-level functions of script
 tag source they do in all those other cases too.

It's not intended for implementing debuggers. I suspect a debugging
API would require something significantly more complex in order to
deal with all the features I listed. For one, how would you deal with
the fact that workers can cause scripts to compile and evaluate on
multiple threads?

If you have suggestions I'm all ears.

/ Jonas


Re: [whatwg] script features

2010-08-17 Thread John J. Barton

 On 8/17/2010 6:43 PM, Jonas Sicking wrote:

...
[1] http://www.whatwg.org/specs/web-apps/current-work/#executing-a-script-block


Ok so I see where executing a script block becomes executing script.

(though I'm not sure which environment is compiled in other than
the global object, which you can't replace anyway, at least not for
now).


Well if I intercept the event and change the source to
   with(browserShim) {
  ... script tag contents here
   }
Then I compile into another environment. Otherwise how can I achieve your
goal?

These events in and of themselves doesn't allow you to modify the
script source. This does seem like a neat idea, if you have ideas for
how this would be done please do suggest them here.

For example,
myWillExecuteHandler = function(event)
{
var elt = event.target;
var adulterate = with(shim){\n+elt.innerHTML+}\n;
eval(adulterate);
return false; // need some way to abort the script tag in progress.
}


What I was thinking was simply allowing the event handler to do things like:

var oldWrite;
myWillExecuteHandler(event) {
   oldWrite = document.write;
   document.write = myWriteOverride;
}
myDidExecuteHandler(event) {
   document.write = oldWrite;
}
But I guess you don't need events to modify and restore the environment, 
why not just put a script before and after:

script
oldWrite = document.write;
document.write = function(msg) { console.log(msg); }
/script
script
document.write(I command you!);
/script
script
document.write = oldWrite;
/script

If this kind of event were provided for all compilations, Javascript
debugging would make a quantum leap forward in performance and reliability.
Firebug, for example, uses egregious hacks to fake these events on the
mozilla platform.


This feature is not enough for that. For example this event is not
fired for onXXX event handlers, calls to eval(), calls to the Function
constructor, calls to WorkerGlobalScope.importScripts or loading of
Workers and SharedWorkers.


But if you don't cover these paths then I don't think the feature is
complete, because what ever developers do in top-level functions of script
tag source they do in all those other cases too.

It's not intended for implementing debuggers. I suspect a debugging
API would require something significantly more complex in order to
deal with all the features I listed. For one, how would you deal with
the fact that workers can cause scripts to compile and evaluate on
multiple threads?
Again, its not a debugging API, it's just the same API you propose.  If 
workers cause scripts to compile, and it triggers event handlers they 
run on the worker thread (and consequently cannot operate on the UI).  
And if you want to talk about complex, let's talk about what developers 
have to do now or what debugger have to do to try to help them.

 jjb


[whatwg] script features

2010-08-16 Thread Jonas Sicking
Hi All,

I'd like to propose a couple of simple features to make script
elements more useful:

1. document.currentScript

This property returns the currently executing script, if any.
Returns null if no script is currently executing. In the case of
several nested executing scripts, it returns the innermost one. This
is useful for being able to pass parameters to the script by setting
data- attributes on the script element.

I think jQuery already does things that requires knowing which
script element linked to jQuery, and it approximates this property
by getting the last element in
document.getElementsByTagName(script), which won't work reliably.
Especially with features like script async.

2. scriptwillexecute/scriptdidexecute events

These events fire right before and right after a script is executed.
This allows a page to override the context a specific script is
seeing. For example installing compatibility shims for older browsers.
Another possible use for this is to make ads execute asynchronously.
Currently this is problematic because a lot of ads use document.write
and so the content will be lost (or worse) if an async attribute is
added to the script element used to load the ad. Using these events
a page can override document.write while a specific script is
executing and insert the written content into the DOM.

(I've written an implementation for firefox for these features here:
https://bugzilla.mozilla.org/show_bug.cgi?id=587931)

/ Jonas