vessillo / foxreplace

Automatically exported from code.google.com/p/foxreplace
0 stars 0 forks source link

New Scripts, fail to execute #75

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Use FoxReplace to insert a NEW JavaScript script element
2. example: AAA<script type="text/javascript"> document.write("<p>My First 
JavaScript</p>"); </script>EEE
3.

What is the expected output? 
AAA

My First JavaScript

EEE

What do you see instead?
AAAEEE

What version of the product are you using? On what operating system?
FoxReplace 0.12.2
FireFox 3.6.28
XP Sp3

Please provide any additional information below.
This may be related to the "can't change JavaScript" issue, but I don't think 
it is. I think that the new script is not executing, and the Change issue is 
likely a much bigger problem.

It also may not be just a simple trigger of the new code. When writing 
JavaScript on the fly into a webpage it takes a bit of wrangling to get it to 
work. see: 
http://stackoverflow.com/questions/53945/dynamically-inserting-javascript-into-h
tml-that-uses-document-write
However that requires some hard coded JavaScript too, which doesn't exist in 
that pages FireReplace is acting on. So it would have to be written into the 
extension I believe.

Original issue reported on code.google.com by mpheyse%...@gtempaccount.com on 13 Jul 2012 at 2:59

GoogleCodeExporter commented 9 years ago
I will take a look at it.

Original comment by marc.r...@gmail.com on 13 Jul 2012 at 3:31

GoogleCodeExporter commented 9 years ago
It seems that the Script code blocks just read once, and changing the page 
doesn't make the page be re-read by the script parser. so new code isn't 
run/parsed.

But adding a new <a> tag with a 'onmouseover' command is parsed during the 
mouseover event and the new code does run. Its not automatic (like regular code 
during a page load) but its a step in the right direction

Original comment by mpheyse%...@gtempaccount.com on 13 Jul 2012 at 11:10

GoogleCodeExporter commented 9 years ago
This allows automated new linear code

<img id="FoxReplaceJSKS" src="&&&&&" onerror="/*Code goes 
here*/alert('Loaded');/*Remove 
Node*/document.getElementById('FoxReplaceJSKS').parentNode.replaceChild(document
.createTextNode('Your Replacement 
text'),document.getElementById('FoxReplaceJSKS'))">

Just add any code you want in place of "alert('Loaded');" and put your actual 
replacement text in 'Your Replacement text'

So this inserts a IMG tag with a Valid but non-existent src entry, so the 
Onerror event is triggered and your NEW code is run. The ending bit, then 
deletes/replaces the IMG tag with the text you want. This prevents your code 
from being rerun a second time, and prevent ID conflicts with further 
replacements.

The limitation is you can't add functions. Any calls to the NEW function will 
bring up a not-defined error

Original comment by mpheyse%...@gtempaccount.com on 14 Jul 2012 at 12:43

GoogleCodeExporter commented 9 years ago
This code lets you import new code and Functions from an external file

var headID = document.getElementsByTagName('head')[0];var newScript = 
document.createElement('script');newScript.type = 
'text/javascript';newScript.src = 
'http://www.w3schools.com/js/myScript.js';headID.appendChild(newScript);

So simply put this code (which is linear) in the above automated <img> tag and 
it will load/run the external .js file.

The Code/Funtions from the external file do persist past the end of the <IMG> 
tag, but all the locals (i.e. headID) are gone. So its nice and clean.

The Major limitation is that the .js file must be on some web site do to the 
un-override-able limitations of FireFox's security.

The simple .js file referenced above defines a callable function [myFunction] 
that replace the text of a tag id="demo" with "My First External JavaScript"

ISSUE 17
And as a note to Users looking for a workaround to issue 17, Firefox allows you 
to redefine functions by simply declaring them a second time. Only the most 
recently defined copy is used. So while you can't replace bits of code in a 
function using the text/replace, you can simple re-declare the function with 
the changes you want.

Again using the myScript.js, Lets say you have the following on the website.

<script type="text/javascript">
function myFunction()
{
document.getElementById("Nock").innerHTML="My Original JavaScript";
}
</script>

But you want to replace the id 'Nock' with 'demo', and have the string read 'My 
First External JavaScript'

By using the above method to load myScript.js, will redefine myfuntion() with 
those changes

function myFunction()
{
document.getElementById("demo").innerHTML="My First External JavaScript";
}

now any calls to myFunction() will act on 'demo' and print 'My First External 
JavaScript'

So here is the whole thing with automation (just change 
'http://www.w3schools.com/js/myScript.js' and 'Your Replacement text') :
<img id="FoxReplaceJSKS" src="&&&&&" onerror="var headID = 
document.getElementsByTagName('head')[0];var newScript = 
document.createElement('script');newScript.type = 
'text/javascript';newScript.src = 
'http://www.w3schools.com/js/myScript.js';headID.appendChild(newScript);document
.getElementById('FoxReplaceJSKS').parentNode.replaceChild(document.createTextNod
e('Your Replacement text'),document.getElementById('FoxReplaceJSKS'))">

Original comment by mpheyse%...@gtempaccount.com on 14 Jul 2012 at 7:14

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
And here is how to add/change code live (no file)

change the newScript.src= into newScript.text='your code here'

ALL the code in newScript is a string in a string, so all strings in your code 
must be escaped single quotes! If this is a problem then I suggest you use the 
.js file where you are not restricted.

Here is a working example where I change the JavaScript on a live website

http://www.anaesthetist.com/mnm/javascript/calc.htm

The "C" button calls a clear function that sets the current value to '0'

The following replacement changes the Function to reset the vale to a string

<img id="FoxReplaceJSKS" src="&&&&&" onerror="var headID = 
document.getElementsByTagName('head')[0];var newScript = 
document.createElement('script');newScript.type = 'text/javascript'; 
newScript.text = 'function Clear() { Current = \'CLEARED BY FOXREPLACE 
JavaScript\';document.Calculator.Display.value = 
Current;};';headID.appendChild(newScript);document.getElementById('FoxReplaceJSK
S').parentNode.replaceChild(document.createTextNode('be 
ambitious.'),document.getElementById('FoxReplaceJSKS'))">

I've attached a FoxReplace XML of this example to make it easier for others to 
test.

Also of Note in the same operation I'm changing the Text "be too ambitious." to 
"be  ambitious." So that There is only one replacement per reload. Not required 
but handy if your real goal is just to insert code.

Original comment by mpheyse%...@gtempaccount.com on 14 Jul 2012 at 9:05

Attachments:

GoogleCodeExporter commented 9 years ago
Thanks for your great work! I will think about how to integrate this solution 
in FoxReplace in a clean and unobtrusive way.

Original comment by marc.r...@gmail.com on 15 Jul 2012 at 3:01

GoogleCodeExporter commented 9 years ago
Well my thought was to add a new inputype called 
FxRSubstitution.prototype.INPUT_JAVA_SCRIPT = 3;

And then just before you squash any non-defined types to INPUT_TEXT

We add the required extra js code to make it fire. Then the auto squash, does 
its thing and were back to a normal text replacement for the rest of the 
replacement.

I was kinda writing it in at this moment since I hadn't heard anything for a 
few days

My syntax is like this

Choose Javascrpt as a type from the dropdown box (icon is "JS")

The replace textbox is for Plain Text part using a '|' seperator
  So to find "57890" in the file and replace it with "4322" you would enter
    "57890|4322"
  Also "57890|" would simply delete the text
  And "57890" would be the equivalent to "57890|57890" would would leave no change (a true insertion)

The 'with' box is where your javascript code would go

IF however you prepend the 'replace' box with "#script#"
then the with box is a .js file location (see comment 5)
    so "#script#57890" would add an external file and not change the html

I'm also making the ID FoxReplaceJSKS include a unique number so multiple 
replacement in the list don't conflict

Original comment by mpheyse%...@gtempaccount.com on 15 Jul 2012 at 6:11

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Its now working in native code 

Here is my change log

FoxReplace 0.12.2
FireFox 3.6.28
XP Sp3

UI Annoyance / Suggestion (Substitution list - URL)

In Def.js
Change
  if (this.inputType < this.INPUT_TEXT || this.inputType > this.INPUT_JAVA_SCRIPT) this.inputType = this.INPUT_TEXT;

add:
FxRSubstitution.prototype.INPUT_JAVA_SCRIPT = 3;

change:
FxRSubstitution.prototype.INPUT_TYPE_STRINGS = ["text", "wholewords", "regexp", 
"javascript"];

In Bindings.dtd
add:
<!ENTITY javaScript "JavaScript Code">

In FoxReplace.properties
add:
javascript=JavaScript Code

inputtextbox-icons.png
Add additional icon Field JS

In Bindings.css
add:
.inputTextBoxButton[inputtype="3"], 
.inputTextBoxButtonMenuItem[anonid="itemJavaScript"] {
  -moz-image-region: rect(0px, 64px, 16px, 48px);
}

add:
.inputTextBox[inputtype="3"] {
  background-color: blue !important;
}

in Bindingd.xml
add:
          <xul:menuitem class="menuitem-iconic inputTextBoxButtonMenuItem" anonid="itemJavaScrpt" label="&javaScript;"
                        oncommand="document.getBindingParent(this).inputType=FxRSubstitution.prototype.INPUT_JAVA_SCRIPT;"/>

change:
          <![CDATA[
            if (val < FxRSubstitution.prototype.INPUT_TEXT) val = FxRSubstitution.prototype.INPUT_TEXT;
            if (val > FxRSubstitution.prototype.INPUT_JAVA_SCRIPT) val = FxRSubstitution.prototype.INPUT_JAVA_SCRIPT;
          ]]>

Add:
            case FxRSubstitution.prototype.INPUT_JAVA_SCRIPT: this._textBox.emptyText = "&javaScript;"; break;

In foxreplace.js
change:
     if (group.html || group.inputType == group.INPUT_JAVA_SCRIPT) this.replaceHtml(doc, group);
     else this.replaceText(doc, group);

Primary Code: In Def.js, FxRSubstitution.prototype = { replace: 
function(aString) {

    if (this.inputType == this.INPUT_JAVA_SCRIPT) {
      //This is a Java script replacement, which needs additional code to parse
      // by ading a Java Kick Start IMG tag

      //For simplicy the inputStringTextBox has both the input and output plain text serparated by '|'
      //And ouputStringTextBox is the js code

      var inoutpar = this.input.split("|",2);
      var jscode = this.output;
      var UnqueTagID= "12344556"; //make random later
      var iscodefragmen= true;    //defalt is raw code
      var scriptslpit=inoutpar[0].split("#script#",2);

      if (scriptslpit[0].length == 0) {
        iscodefragmen= false;  //is adress of .js file
        inoutpar[0]=scriptslpit[1]; //remmove the #script# flag
      }

      if (inoutpar.length == 1)  {
        //had no pipe
        inoutpar.splice(0,0,inoutpar[0]); // dups the entry making "me" into the eqivelent of "me|me"
      }  

      //run re-escape processess here
        //the script can only have \' and lower quotes

        //try making all " into \\\" might work as the on error would see it as \"
      //needs testing, leave \' restriction for now

      var tagprefix = "<img id=\"FoxReplaceJSKS" + UnqueTagID + "\" src=\"&&&&&" + UnqueTagID + "\" onerror=\"var headID = document.getElementsByTagName('head')[0];var newScript = document.createElement('script');newScript.type = 'text/javascript'; ";
      var tagcodefg = "newScript.text = '";
      var tagscript = "newScript.src = '";
      var tagmidfix = "';headID.appendChild(newScript);document.getElementById('FoxReplaceJSKS" + UnqueTagID + "').parentNode.replaceChild(document.createTextNode('";
      var tagpstfix = "'),document.getElementById('FoxReplaceJSKS" + UnqueTagID + "'))\">";

      this.input=inoutpar[0]
      if (iscodefragmen)  {
        this.output=tagprefix + tagcodefg + jscode + tagmidfix + inoutpar[1] + tagpstfix;
      } else  {
        this.output=tagprefix + tagscript + jscode + tagmidfix + inoutpar[1] + tagpstfix;
      } 
      // now treat as a regular INPUT_TEXT  HTML replacement
      this.inputType = this.INPUT_TEXT ; 
    //End Input_Java_Script
    }

I'm hoping to figure a way around the \' limitation of the direct script 

I'll also post a full file set so user who want to try can.

Original comment by mpheyse%...@gtempaccount.com on 16 Jul 2012 at 1:28

GoogleCodeExporter commented 9 years ago
Here are the files for JavaScript FoxReplace, I've also updated the help file.

These are for FoxReplace 0.12.2, just replace the ones to have. I've Tested it 
on XP but it should work on most I would think.

This does have the \' limitation, and there is no check for that. I'll work on 
that but I figure people might want full working program first. (And .js files 
are FULLY OPERATIONAL)

Original comment by mpheyse%...@gtempaccount.com on 16 Jul 2012 at 4:18

Attachments:

GoogleCodeExporter commented 9 years ago
Opps forgot to make UnqueTagID actually be different. So lots of JavaScript 
replacements may conflict (none of my tests have so far).

also post any problems you have with this HERE, until it get put into a 
official 0.12.2.1 version

Original comment by mpheyse%...@gtempaccount.com on 16 Jul 2012 at 4:23

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
This set now has UnqueTagID working

Also the \' restriction is gone. Any JavaScript can be inserted without 
alteration, as the internals do all the mangling for you.

I may have missed some odd mangling but none that I've yet found. Please report 
if you find any.

Also there may be practical length limits but I don't know what they might be. 
If you have a LOT of code in a single function, either put it in a .js file or 
break it up into sub functions

You can do many JavaScript replacements (its just like multiple <script> tags)

You just need the defs.js file,  but the foxreplace.jar has an updated Help.dtd 
if you read the help

Original comment by mpheyse%...@gtempaccount.com on 16 Jul 2012 at 3:07

Attachments:

GoogleCodeExporter commented 9 years ago
*Disclaimer to other readers: please note that I have not released nor revised 
nor tested the files attached in this issue, they are not official, so if you 
want to use them do it at your own risk; I don't take any responsibility on it 
and I won't work on issues you find with them.*

-------------------

To the poster: Thanks for your contribution, but I will have to revise the code 
in depth before I consider including it in the official code.

What I can tell you right now is that I don't like your idea of using the input 
field ("replace") for both input and output in this case. It's bad UI design. 
Also, there are some changes in the current code (which is version 0.13.1) that 
make your code incompatible.

Original comment by marc.r...@gmail.com on 16 Jul 2012 at 4:34

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
yep That's why I said "until an official version"

The "field ("replace") for both input and output" was that I didn't want to do 
any major changes to your UI (I just added one more icon, and more error 
checking). Just to get it running with what we have, and as little changes as 
possible. 

Also if they just ignore it, and type only an input text, the UI treats it as 
an insertion point (essentially no replacement only script injection). This 
would be the most common use and the whole dual in|out is really 
optional/Advance notation.

And really using two Icons instead of the '#script# notation is probably a 
better way to go. [say 'JavaScript Code' (JSC) and 'JavaScript File' (JSF)] 
What I do like about '#script# notation, is that in the list box, the .js file 
lines are easy to identify.

I'm changing 12.2 because it current for my system, and FF tells met 13.1 
isn't. 
I hope that a official release for 12.2 or a 13.x that support my environment 
comes along.

I hope the comments help, and I could post a new change log if it would help.

*Disclaimer, all CODE and FILES posted in this issue are by me, and are not 
OFFICIAL. They may, albeit unintentional, cause all symptoms laid out in song 
"Virus Alert" by "Weird Al Yankovic" but I tried my best.*

Original comment by mpheyse%...@gtempaccount.com on 17 Jul 2012 at 1:12

GoogleCodeExporter commented 9 years ago
I misunderstood the part about the official 0.12.2.1 version, and just wanted 
to make sure nobody who reads this thread in the future is confused.

I'm sorry to tell you that there won't be a 0.12.2.1 or 0.12.3 version. The 
next version will be 0.13.2 or 0.14.0 or 1.0.0 (unlikely). Also I don't plan to 
support Firefox 3.6 in any future release. I tested the current FoxReplace 
version on it and it didn't work fully. Now I think it may be the same case as 
issue 80, which is caused by an undefined reference, but since Firefox 3.6 is 
not supported by Mozilla anymore, I don't plan to test it or marking it as 
compatible. (But you can, if you want, try it with Add-on Compatibility 
Reporter 
(https://addons.mozilla.org/en-US/firefox/addon/add-on-compatibility-reporter/) 
and use it if it works, while you are still on Firefox 3.6.)

Original comment by marc.r...@gmail.com on 17 Jul 2012 at 5:49

GoogleCodeExporter commented 9 years ago
Found a new issue, The replacement Text isn't currently escaped but does pass 
through the same HTML string just like the code does.

So if your replacement text has a " in it, it will break the string.

I'll get on that

Original comment by mpheyse%...@gtempaccount.com on 20 Jul 2012 at 4:52

GoogleCodeExporter commented 9 years ago
There are also issues with document.write() which is how normally the output of 
a JavaScript gets printed on a page. 

The problem is that document.write() adds to the "stream" of the in-progress 
HTML parsing. FoxReplace however is acting on a fully complete page, so writes 
to the 'Stream' replaces the Entire page.

Ideally what we want is for calls to document.write()to be inserted into the 
document at our 'replace' position, and of course NOT hose the page.

I'm working on this too

Original comment by mpheyse%...@gtempaccount.com on 20 Jul 2012 at 5:22

GoogleCodeExporter commented 9 years ago
The replacement Text now supports " characters properly.    

And I now have working 'stream emulation' so that document.write() will work as 
intended.

During the first execution/load document.write()calls write to the page in the 
place that FoxReplace put the script. Later calls (out-of stream) behave just 
like normal, (deleting the entire page)

However this only works on direct Code fragments, and not external #script# .js 
files.

It works by adding a <FRnull> tag as a reference point. Think of it as a <a> 
tag that doesn't break existing <a> tags (which it would have, had I used 
them). Prior to insertion, all calls to document.write() in your code are 
replace to a unique function called FoxReplaceJSKS##########DocWrite(). That 
function is prepended to your code, and will add your writes to the <FRnull> 
tag. Then after your code a statement that deletes the id= attribute of the 
<FRnull> tag is add to the end.

The function looks like this
function FoxReplaceJSKS##########DocWrite(PrintText) {
  try {
    document.getElementById('FoxReplaceJSKS' + UnqueTagID 'Atag').innerHTML=document.getElementById('FoxReplaceJSKS' + UnqueTagID 'Atag').innerHTML + PrintText; 
  }
  catch(err) {
    document.write(PrintText);
  }
}

So when your code is done executing/loading, FRnull> tag 'id' is removed. Then 
future calls to FoxReplaceJSKS##########DocWrite() are sent to the normal  
document.write()

This does leave the blank <FRnull> tag in the page structure (not perfectly 
clean). but to remove it, all of its children would have to be first moved into 
the correct spot in the parent node. That slows us down, and changes the page 
structure between initial run and future runs of your code functions. Leaving 
it in place just seemed to be the better option.

The problem with .js files is that I can to the initial renaming of your 
functions. 

I've also reworked the internal variable names and improved to commenting to 
make the internals easier for others (Marc) to read and understand. The parser 
levels can get tricky.

If you skipped all that:

Basically document.write() now works as normal in code, and is always 
out-of-stream in .js files (deletes page) 

Here is the defs.js I haven't yet updated the help file.

any issues please post.

*Disclaimer, all CODE and FILES posted in this issue are by me, and are not 
OFFICIAL. They may, albeit unintentionally, cause all symptoms laid out in song 
"Virus Alert" by "Weird Al Yankovic" but I tried my best.*

Original comment by mpheyse%...@gtempaccount.com on 21 Jul 2012 at 9:01

Attachments:

GoogleCodeExporter commented 9 years ago
Just wanted to say, I'm using this new JavaScript functionality daily on 
multiple websites, and while I do have a new issue, its unrelated to this. 
Thanks, Marc

Original comment by mpheyse%...@gtempaccount.com on 30 Oct 2012 at 2:05