Tom
Tom

Reputation: 3044

How in JavaScript fetch line from which the function was called?

The code below shows my almost complete page source (without doctype) and line number from where test() was called. Because code does not contain doctype then I when I do alert(code[line]) I don't get the right line.

<script>
function test(what)
{
    var err = new Error;
    var line = err.stack.split("\n")[1].split(':')[2];
    var code = document.documentElement.outerHTML.split("\n");
    console.log(code);
    alert(line);
}

test('hello there');
<script>

How do I get 'test('hello there');' from my test function as a string?

The problem is with line numbering. My line returns the correct line number as in the source file, but my code returns page source with different numbering (it misses DOCTYPE and have different line breaks). So the question is: how to get the "real" page source?

Upvotes: 0

Views: 146

Answers (2)

Tom
Tom

Reputation: 3044

Here's a working, but ugly solution. Ugly because:
1. Loads the same page again
2. Uses async ajax

<script>
function getSource()
{
    var request = new XMLHttpRequest();

    request.open('GET', location.href, false);
    request.send(null);

    if (request.status === 200) 
    {
        return request.responseText;
    }
    return '';
}
function test(what)
{
    var err = new Error;
    var line = err.stack.split("\n")[1].split(':')[2];
    var code = getSource().split("\n");
    alert(code[line-1]);
}

test('hello there');
</script>

Upvotes: 0

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382464

A solution is to look not in the whole HTML document but in the right script element. It works but you'd need some care before to use it :

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<script>
  function test(what) {
    var err = new Error;
    console.log(err.stack.split("\n"))
    var line = err.stack.split("\n")[2].split(':')[1];
    var script = document.scripts[0];
    var code = (script.innerText||script.textContent).split(/<br>|\n/);
    console.log(line);
    console.log(code, code.length);
    console.log(code[+line]); // this logs "test('hello there');"
}

test('hello there');
</script>
</body>
</html>

The first thing to do would probably be to give an id to your script element instead of relying on the number.

And I really wouldn't use such a thing apart for some short tests.

Demonstration (click "Run with JS")

Upvotes: 1

Related Questions