Bug Tracker

Opened 10 years ago

Closed 9 years ago

#5319 closed bug

Error when passing new String(...) to jQuery.html()

Reported by: bartaz Owned by:
Priority: major Milestone: 1.4
Component: core Version: 1.3.2
Keywords: Cc: bartaz
Blocked by: Blocking:

Description

I found this error when passing a String object to $.fn.html. The simple case looks like this:

$("div").html(new String("test"));

This code throws an error, reported by Firebug as: Could not convert JavaScript argument arg 0 [nsIDOMDocumentFragment.appendChild]

I tracked it down to find that problems seem to be in jQuery.clean function. Strings created from String() constructor have typeof 'object' so are not recognized as strings. So this condition in clean method falis:

// Convert html string into DOM nodes
if ( typeof elem === "string" ) { ... }

Change History (6)

comment:1 Changed 10 years ago by flesler

Cc: bartaz added
Component: unfilledcore
need: ReviewTest Case

Can you provide a test case where you'd pass an objectified string instead of a native one ?

comment:2 Changed 10 years ago by bartaz

I know that using objectified strings is probably not a common case, especially that they get 'stringified' again when concatenated with literal strings:

new String("test") + ""

In my case issue was caused by function extending String prototype. It was 'truncate' function (taken from prototype.js)

String.prototype.truncate = function(length, truncation) {
    length = length || 30;
    truncation = truncation === undefined ? '...' : truncation;
    return this.length > length ?
        this.slice(0, length - truncation.length) + truncation : this;
    };

Let's say I used it like this:

$("div").html(value.truncate(20));

Everything was fine when value was a string longer than 20 chars. It got truncated and displayed. But when it was shorter than 20 chars (so the truncate method returned this) the return value was a String object and html function failed to run.

Whenever you return this from extended String prototype it returns object, not literal string. So simple test case may be function that does 'nothing':

String.prototype.self = function(){ return this; }

What it actuality does is turning literal strings into String objects

I created a page where I run these cases: http://bartaz.github.com/sandbox.js/string_object_test.html

I know that's not a common issue and it has easy workaround (concatenating with empty "" string before putting into html method).

comment:3 Changed 10 years ago by dmethvin

Interesting...i've never returned this explicitly when adding a method but I see what you mean. In general I avoid creating String or Number objects like the plague. There are a few cases where Javascript itself won't accept String objects but will accept literal strings. One that I recall is the argument to eval().

If you have your method return String(this) instead of this it will solve the problem.

This is somewhat similar to #4533 but that one seems easier to fix.

comment:4 Changed 10 years ago by bartaz

Ok, I think it's quite fair to assume that the bug is in 'truncate' function that should return literal strings in both cases.

But when using additional JS libraries sometimes you don't know if you will always get literal (not object) strings and may be surprised when passing them into jQuery.

It seems to be quite easy to fix, so would be nice to have.

comment:5 Changed 9 years ago by snover

Status: newpending

This ticket has been marked as missing a test case. In an effort to reduce the number of outstanding tickets in the bug tracker, it will be closed automatically in 30 days. In order to prevent this from happening, please provide a working test case. If a test case has already been provided and our records are wrong, please respond to the ticket so that it can be fixed. Thank you!

comment:6 Changed 9 years ago by trac-o-bot

Status: pendingclosed

Automatically closed due to 14 days of inactivity.

Note: See TracTickets for help on using tickets.