Kodewerx

Our culture has advanced beyond all that you could possibly comprehend with one hundred percent of your brain.
It is currently Tue Mar 19, 2024 2:45 am

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 14 posts ] 
Author Message
PostPosted: Tue Nov 10, 2009 6:51 pm 
Offline
Komrade
Komrade

Joined: Tue Mar 27, 2007 10:18 am
Posts: 1328
Code:
<script language="javascript" type="text/javascript">
function changeSpanColor{option}() {
if (typeof changeSpanColor{option}.test == 'undefined') {
changeSpanColor{option}.test = 0;
}
changeSpanColor{option}.test++;
changeSpanColor{option}.test %= 24;
var temp = changeSpanColor{option}.test;
if (temp < 12)
temp *= 0x060000;
else
temp = 0x480000 - ((temp - 12) * 0x060000);
temp += 0x800000;
temp = '#' + temp.toString(16);
document.getElementById("testSpan{option}").style.color = temp;
setTimeout("changeSpanColor{option}()", 125);
}
</script>
<span id="testSpan{option}"><strong>{content}</strong></span>
<script language="javascript" type="text/javascript">
changeSpanColor{option}();
</script>

This is in the context of an IPB forum, so {content} and {option} can be used as macros for the innards of a BBCode tag.

The gratuitous misuse of {option} was my hacky solution to allowing more than one of these on a page. If I could get it to work with a single function (or no function at all, as one of my attempts was) then I'd put the function in the board header where it belongs.

Alas, I do not actually know JavaScript. So here I am. Para, halp, etc.

_________________
Image


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 10, 2009 9:04 pm 
Offline
Krew (Admin)
Krew (Admin)
User avatar

Joined: Sun Oct 01, 2006 9:26 pm
Posts: 3768
Title: All in a day's work.
Not sure what you are trying to do, so I'm just going to attempt to modify your code into something that makes a little more sense (rather than providing a real solution ... which might be possible if you specify the inputs and expected output!)

First, reference the function itself with the 'this' keyword. Also, pass part of the element id as an argument to the function, rather than putting it into the function's name. The prototype will set the default value of the 'test' member. setInterval() is designed to execute code several times with a specific delay between each call; much better than setTimeout() for this purpose. I opted to use an event listener on the document's "load" event, instead of using a separate script to start the interval running. And finally, I optimized your algorithm slightly.

Code:
<script language="javascript" type="text/javascript">
function changeSpanColor(id) {
    if (typeof this.test == 'undefined') {
        this.test = 0;
    }
    this.test++;
    this.test %= 24;
    var temp = this.test;
    if (temp > 12)
        temp = 23 - temp;
    temp *= 0x060000;
    temp += 0x800000;
    document.getElementById("testSpan" + id).style.color = "#" + temp.toString(16);
}

changeSpanColor.prototype = {
    test: 0
};

function init() {
    setInterval(changeSpanColor, 125, "{option}");
}

if (window.addEventListener) {
    window.addEventListener("load", init, false);
}
else if (window.attachEvent) {
    window.attachEvent("onload", init);
}
</script>

<span id="testSpan{option}"><strong>{content}</strong></span>

_________________
I have to return some video tapes.

Feed me a stray cat.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Nov 10, 2009 10:24 pm 
Offline
Komrade
Komrade

Joined: Tue Mar 27, 2007 10:18 am
Posts: 1328
That looks much more like what I was going for. I had similar thoughts in mind for what you explained you had done (aside from optimizing the algorithm; I had a feeling it wasn't optimal but I was more concerned with the hideous hack I was doing), but I didn't know how to translate them into the language because...like I said, I don't know the language (for example: my attempts to set an "onload" handler involved some parameter I was giving to the span element, which I soon learned was retarded of me). This was the first bit of code I had written in it, and was composed of some stuff I slapped together after minimal Googling.

I'll have to try it later; I have a test tomorrow and I'm way behind on preparing for it...

I believe your revision would allow for placing some things in the HTML header, but because the forum has multiple skins and therefore multiple HTML headers, I'd be mucking around with more code if I optimized it that way. I'm not sure which is cleaner...

_________________
Image


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 13, 2009 3:49 pm 
Offline
Krew (Admin)
Krew (Admin)
User avatar

Joined: Sun Oct 01, 2006 9:26 pm
Posts: 3768
Title: All in a day's work.
After thinking about this more, you probably want to include an arbitrary number of those span elements to flash. A better solution than creating a new interval timer for each element, you probably want to just create the one interval and give all your elements a specific attribute than can be selected by JS/CSS. Then you just have to iterate through all of the elements that match your selector. Probably the "name" attribute would be sufficient:

Code:
<script language="javascript" type="text/javascript">
function changeSpanColor(name) {
    if (typeof this.test == 'undefined') {
        this.test = 0;
    }
    this.test++;
    this.test %= 24;
    var temp = this.test;
    if (temp > 12)
        temp = 23 - temp;
    temp *= 0x060000;
    temp += 0x800000;

    var nodes = document.getElementsByName(name);
    for (var i = 0; i < nodes.length; i++) {
        nodes[i].style.color = "#" + temp.toString(16);
    }
}

changeSpanColor.prototype = {
    test: 0
};

function init() {
    setInterval(changeSpanColor, 125, "{option}");
}

if (window.addEventListener) {
    window.addEventListener("load", init, false);
}
else if (window.attachEvent) {
    window.attachEvent("onload", init);
}
</script>

<span name="{option}"><strong>{content}</strong></span>


I haven't tested it explicitly, but it should work great. Since you can give all of the elements the same name, JS can update them all at the same time.

_________________
I have to return some video tapes.

Feed me a stray cat.


Top
 Profile  
Reply with quote  
PostPosted: Tue Feb 09, 2010 12:18 am 
Offline
Komrade
Komrade

Joined: Tue Mar 27, 2007 10:18 am
Posts: 1328
BUMP!

Alright, Para, I got another one for you.

This is all well and good:

Code:
javascript:document.location.href="http://www.bungie.net/Stats/GameStatsHalo3.aspx?gameid=1547718084&player=l%20xbl%20warror%20l";

Throwing that in a link would take people with JS enabled to that page.

But what if I want to do this:

Code:
javascript:StatsToggleSection('pnlKills', 'tabKills');

Upon completion of loading the target page? I can't seem to figure out how to include the second snippet as an addendum to the first so that when the user clicks the link, it not only brings them to the page but initializes the form appropriately. I can't imagine why it wouldn't be possible.

Halp.

_________________
Image


Top
 Profile  
Reply with quote  
PostPosted: Tue Feb 09, 2010 4:40 pm 
Offline
Krew (Admin)
Krew (Admin)
User avatar

Joined: Sun Oct 01, 2006 9:26 pm
Posts: 3768
Title: All in a day's work.
Ah, what you're talking about is cross-site scripting (XSS); loading a target page (hosted by bungie.net) and then manipulating the contents of that page. XSS is considered a security risk, so browser architecture limits (or disables) functionality that would allow scripts on one site to control another.

You might be able to do a cross-site request forgery (XSRF) if bungie.net doesn't do any kind of guards against it.

But a far more reliable work-around is building an HTTP proxy (written in PHP or such) that loads the page on bungie.net, filters the HTML/scripts to link back to the proxy itself, and appends any kind of HTML or script that you would like. The filtered content is just served to the user directly. It's a little more complicated, but it gives you the kind of control over the page that you're looking for.

I wrote such an HTTP proxy in PHP some years ago (very simple in design) if it would be any use.

_________________
I have to return some video tapes.

Feed me a stray cat.


Top
 Profile  
Reply with quote  
PostPosted: Tue Feb 09, 2010 9:04 pm 
Offline
Komrade
Komrade

Joined: Tue Mar 27, 2007 10:18 am
Posts: 1328
That's actually what I was thinking of, but I was hoping to avoid "forging" anything if I could.

(My idea was something like "well if all else fails I could potentially design a page that becomes what's at the location I want to manipulate and then deals with it accordingly, then simply bit.ly what I've produced", but to be fair I didn't have any idea of how to efficiently load the page's contents in "my own" for those purposes)

Yeah, I had a feeling this might be something devious.

Speaking of playing with Javascript, I seem to recall some old online game I found an exploit in involving inputting arithmetic expressions into input fields having its validation code right there in the HTML source in the form of JS; the exploit I spoke of was removed eventually, but others remain, including (if I remember correctly) the validation code being client side.

Edit: Nope, turns out my memory was all too fuzzy.

The site also seems to no longer let me do a post from a personally created page stored on my disk. Which means I can no longer input values to statistics that should remain unchanged when submitting the starting stats for newly created characters...

I bet the rounding abuse is still there, though! I just confirmed I can still delete characters off of others' accounts...

_________________
Image


Last edited by Hextator on Tue Feb 09, 2010 9:44 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Tue Feb 09, 2010 9:41 pm 
Offline
Krew (Admin)
Krew (Admin)
User avatar

Joined: Sun Oct 01, 2006 9:46 pm
Posts: 2331
Location: *poof*
Title: The Mad Hacker
Parasyte wrote:
...
I wrote such an HTTP proxy in PHP some years ago (very simple in design) if it would be any use.

I'd be interested in looking at it if you wouldn't mind posting it.

_________________
Image


Top
 Profile  
Reply with quote  
PostPosted: Wed Feb 10, 2010 6:00 pm 
Offline
Krew (Admin)
Krew (Admin)
User avatar

Joined: Sun Oct 01, 2006 9:26 pm
Posts: 3768
Title: All in a day's work.
Note: An update to this script is available here: viewtopic.php?f=5&t=7334&p=78054#p78054

index.php:
Code:
<?php

// ENABLE FOR DEBUGGING ONLY
ini_set("display_errors", '1');

function get_var_GET($varname) {
    $varname = $_GET[$varname];
    if (!get_magic_quotes_gpc()) $varname = addslashes($varname);

    return $varname;
}

$url = get_var_GET('url');

if (substr($url, 0, 7) == 'http://') {
    $path = substr($url, 0, strrpos($url, '/'));
    $domain = substr($url, 0, strpos($url, '/', 7));

    $lines = file($url);
    foreach ($lines as $line) {
        $line = preg_replace('/(<a [^<>]* ?href ?= ?["\']?)([\w:\/.\?&;=]+)([" >])/ie', '"$1index.php?url=" . (substr("$2", 0, 1) == \'/\' ? urlencode("$domain$2") : urlencode("$path/$2")) . "$3"', $line);
        $line = preg_replace('/<img [^<>]*>/i', '', $line);
        $line = preg_replace('/(<form [^<>]* ?action ?= ?["\']?)([\w:\/.\?&;=]+)([" >])/ie', '"$1index.php?url=" . (substr("$2", 0, 1) == \'/\' ? urlencode("$domain$2") : urlencode("$path/$2")) . "$3"', $line);
        echo $line;
    }
}
else {
    echo '<form method="get" action="index.php"><input name="url" type="text" value="http://"><input type="submit" value="Go"></form>';
}

?>


Note that it doesn't do any kind of input validation... Verifying that the crap you entered is actually a URL. Even scarier, it doesn't check if it's trying to access files hosted on its own server, which could lead to information leaks (loading PHP scripts/configuration files/password files and serving them plain-text?) ...

And I never bothered to filter images, so they are simply stripped. There's other external resources that are not filtered properly, either... For example, <script>, <link>, <style>, <input type="image">, ...

_________________
I have to return some video tapes.

Feed me a stray cat.


Top
 Profile  
Reply with quote  
PostPosted: Fri May 14, 2010 3:54 am 
Offline
Komrade
Komrade

Joined: Tue Mar 27, 2007 10:18 am
Posts: 1328
I just wanted to bump this to report that I think I have a better solution to my BBCode issue.

For one thing, since as you say elements can share names, I could remove the need for the {option} specification altogether, which greatly simplifies things.

For another, a thing I'm working on now does not want to iterate through spans that have already been processed, so I'm simply removing the name attribute from each one as it is examined. I can get what I need done without putting the html/JS anywhere but in the BBCode definition and, had I used IDs, I'd be removing them anyway so there wouldn't be an issue (so long as I remove support for tags that let users specify name or id attributes, which I really should). As well, despite the code appearing redundantly, the ability to minimize its execution and not have to separate it (modularity is REALLY inconvenient for this; ironically because of a lack of modularity elsewhere) keeps it efficient.

Edit:

Why does

Code:
for (node in nodes)

give "node" as a string when

Code:
for (var i = 0; i < nodes.length; i++)

gives nodes[i] as a span when nodes is an array of spans? That's just bad design.

Edit: I am incredibly proud of this (yes, the BIFF sig).

And yeah. I really do hate pre tags.

_________________
Image


Top
 Profile  
Reply with quote  
PostPosted: Fri May 14, 2010 4:01 pm 
Offline
Krew (Admin)
Krew (Admin)
User avatar

Joined: Sun Oct 01, 2006 9:26 pm
Posts: 3768
Title: All in a day's work.
You must never use the for...in pattern on an Array because it returns object properties. That means it will not only return array elements (which are JS object properties!) but it will also return properties like Array.length and Array.constructor, which is probably what you are seeing.

You might want to look into Array.forEach() ... but old crappy versions of IE don't support it natively, so if you want it to work on that garbage, you can use this Piece of Awesome that I wrote for phpiCalendar:

Code:
// IE does not support the Array.forEach() method... Try to approximate it
if (!Array.prototype.forEach) {
    Array.prototype.forEach = function(action, context) {
        var len = this.length;
        for (var i = 0; i < len; i++) {
            if (this[i] != undefined) action(this[i], context);
        }
    };
}

_________________
I have to return some video tapes.

Feed me a stray cat.


Top
 Profile  
Reply with quote  
PostPosted: Fri May 14, 2010 6:02 pm 
Offline
Komrade
Komrade

Joined: Tue Mar 27, 2007 10:18 am
Posts: 1328
That's a neat workaround. Anyway, the thing that was being returned was a string, or at least the first thing was. When I tried to display the string, it was simply "0". Why would there be a string as "0"? But in any case, I had a feeling that you wouldn't have posted that code you had earlier that used an integer to iterate unless it were more proper after the foreach loop failed and, of course, when I switched to using an integer index it worked fine.

Now I just need to edit the innerText/textContent of the innermost child of the spans I'm editing so that any nested elements within the span are kept...I'm losing tags as it is unless the span is already the innermost child!

_________________
Image


Top
 Profile  
Reply with quote  
PostPosted: Fri May 14, 2010 8:30 pm 
Offline
Krew (Admin)
Krew (Admin)
User avatar

Joined: Sun Oct 01, 2006 9:26 pm
Posts: 3768
Title: All in a day's work.
Eh? JavaScript doesn't really have a concept of integers. JavaScript has Number objects, which can act like integers (and can even be supported by integers at the byte-code level) or double-precision floating point numbers.

And uh, I don't know what "foreach loop failed" you're talking about. The only use of "foreach" is in the PHP... On the other hand, I also mentioned the forEach method on the Array object, and posted some code to approximate it in IE by modifying the global Array object's prototype. But what's this about failing?

How did you check that the result of your for...in was a string?

if (typeof(node) == "string")
...or...
if (node instanceof String)

(Yes, JavaScript is case-sensitive, keep this in mind.)

_________________
I have to return some video tapes.

Feed me a stray cat.


Top
 Profile  
Reply with quote  
PostPosted: Fri May 14, 2010 9:33 pm 
Offline
Komrade
Komrade

Joined: Tue Mar 27, 2007 10:18 am
Posts: 1328
- For all intents and purposes it was an integer, but yes, I'm aware JS isn't strongly typed.
- What you're calling a "for...in" is just a variation of a foreach loop if you ask me. Mine failed.
- I just printed it.
Code:
document.write("<br />" + typeof obj);

Worked fine. Said "string".

Edit: I suppose explicitly referring to it as a for...in helps with the implication that it's iterating over properties and not elements of a collection. But to me a foreach is just a loop that iterates over a glob of things, regardless of what they are. Whether someone I'm talking to recognizes what that glob of things is is up to them unless it becomes apparent afterward that clarification is needed.

I discuss this with a friend of mine a lot; accounting for things without even determining if you need to first is just inefficient.

_________________
Image


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 15 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group