diff -r a8afba7027ae runtime/doc/indent.txt
--- a/runtime/doc/indent.txt
+++ b/runtime/doc/indent.txt
@@ -431,6 +431,25 @@
 		    }
 		});
 <
+					*javascript-cinoptions* *javascript-indenting*
+	JN    Indent JavaScript object declarations correctly by not confusing
+	      them with labels. The value 'N' is currently unused but must be 
+	      non-zero (e.g. 'J1').
+
+
+		var bar = {
+		    foo: {
+			that: this,
+			some: ok,
+		    },
+		    "bar":{ 
+			a : 2,
+			b: "123abc",
+			x: 4,
+			"y": 5
+		    }
+		}
+
 	)N    Vim searches for unclosed parentheses at most N lines away.
 	      This limits the time needed to search for parentheses.  (default
 	      20 lines).
diff -r a8afba7027ae runtime/indent/javascript.vim
--- a/runtime/indent/javascript.vim
+++ b/runtime/indent/javascript.vim
@@ -11,5 +11,6 @@
 
 " C indenting is not too bad.
 setlocal cindent
+setlocal cinoptions+=j1,J1
 
 let b:undo_indent = "setl cin<"
diff -r a8afba7027ae src/misc1.c
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -5040,7 +5040,7 @@
 	    curwin->w_cursor = cursor_save;
 	    if (cin_isterminated(line, TRUE, FALSE)
 		    || cin_isscopedecl(line)
-		    || cin_iscase(line)
+		    || cin_iscase(line, TRUE)
 		    || (cin_islabel_skip(&line) && cin_nocode(line)))
 		return TRUE;
 	    return FALSE;
@@ -5079,8 +5079,9 @@
  * Recognize a switch label: "case .*:" or "default:".
  */
      int
-cin_iscase(s)
+cin_iscase(s, strict)
     char_u *s;
+    int strict; /* Allow relaxed check of case statement for JS */
 {
     s = cin_skipcomment(s);
     if (STRNCMP(s, "case", 4) == 0 && !vim_isIDc(s[4]))
@@ -5100,7 +5101,13 @@
 	    else if (*s == '/' && (s[1] == '*' || s[1] == '/'))
 		return FALSE;		/* stop at comment */
 	    else if (*s == '"')
+	    {
+		/* JS etc. */
+		if (strict)
 		return FALSE;		/* stop at string */
+		else
+		    return TRUE;
+	    }
 	}
 	return FALSE;
     }
@@ -5159,7 +5166,7 @@
 	{
 	    if (l[1] == ':')	    /* skip over "::" for C++ */
 		++l;
-	    else if (!cin_iscase(l + 1))
+	    else if (!cin_iscase(l + 1, FALSE))
 		break;
 	}
 	else if (*l == '\'' && l[1] && l[2] == '\'')
@@ -5217,7 +5224,7 @@
     curwin->w_cursor.lnum = lnum;
     l = ml_get_curline();
 				    /* XXX */
-    if (cin_iscase(l) || cin_isscopedecl(l) || cin_islabel(ind_maxcomment))
+    if (cin_iscase(l, FALSE) || cin_isscopedecl(l) || cin_islabel(ind_maxcomment))
     {
 	amount = get_indent_nolabel(lnum);
 	l = after_label(ml_get_curline());
@@ -6164,6 +6171,10 @@
     int	ind_java = 0;
 
     /*
+     * not to confuse JS object properties with labels 
+     */
+	int ind_js = 0;
+    /*
      * handle blocked cases correctly
      */
     int ind_keep_case_label = 0;
@@ -6276,6 +6287,7 @@
 	    case 'g': ind_scopedecl = n; break;
 	    case 'h': ind_scopedecl_code = n; break;
 	    case 'j': ind_java = n; break;
+	    case 'J': ind_js = n; break;
 	    case 'l': ind_keep_case_label = n; break;
 	    case '#': ind_hash_comment = n; break;
 	}
@@ -6286,6 +6298,10 @@
     /* remember where the cursor was when we started */
     cur_curpos = curwin->w_cursor;
 
+    /* if we are at line 1 0 is fine, right? */
+    if (cur_curpos.lnum == 1) 
+	return 0;
+
     /* Get a copy of the current contents of the line.
      * This is required, because only the most recent line obtained with
      * ml_get is valid! */
@@ -6320,9 +6336,9 @@
     }
 
     /*
-     * Is it a non-case label?	Then that goes at the left margin too.
-     */
-    else if (cin_islabel(ind_maxcomment))	    /* XXX */
+     * Is it a non-case label?	Then that goes at the left margin too unless JS flag is set.
+     */
+    else if (!ind_js && cin_islabel(ind_maxcomment))	    /* XXX */
     {
 	amount = 0;
     }
@@ -6773,7 +6789,7 @@
 	     *			ldfd) {
 	     *		    }
 	     */
-	    if (ind_keep_case_label && cin_iscase(skipwhite(ml_get_curline())))
+	    if ((ind_keep_case_label && cin_iscase(skipwhite(ml_get_curline()),FALSE)))
 		amount = get_indent();
 	    else
 		amount = skip_label(lnum, &l, ind_maxcomment);
@@ -6851,7 +6867,7 @@
 
 	    lookfor_break = FALSE;
 
-	    if (cin_iscase(theline))	/* it's a switch() label */
+	    if (cin_iscase(theline, FALSE))	/* it's a switch() label */
 	    {
 		lookfor = LOOKFOR_CASE;	/* find a previous switch() label */
 		amount += ind_case;
@@ -6912,7 +6928,7 @@
 			     * initialization) */
 			    if (cont_amount > 0)
 				amount = cont_amount;
-			    else
+			    else if(!ind_js)
 				amount += ind_continuation;
 			    break;
 			}
@@ -7036,7 +7052,7 @@
 		 * If this is a switch() label, may line up relative to that.
 		 * If this is a C++ scope declaration, do the same.
 		 */
-		iscase = cin_iscase(l);
+		iscase = cin_iscase(l,FALSE);
 		if (iscase || cin_isscopedecl(l))
 		{
 		    /* we are only looking for cpp base class
@@ -7160,7 +7176,7 @@
 		/*
 		 * Ignore jump labels with nothing after them.
 		 */
-		if (cin_islabel(ind_maxcomment))
+		if (!ind_js && cin_islabel(ind_maxcomment))
 		{
 		    l = after_label(ml_get_curline());
 		    if (l == NULL || cin_nocode(l))
@@ -7271,7 +7287,7 @@
 			 */
 			curwin->w_cursor = *trypos;
 			l = ml_get_curline();
-			if (cin_iscase(l) || cin_isscopedecl(l))
+			if (cin_iscase(l, FALSE) || cin_isscopedecl(l))
 			{
 			    ++curwin->w_cursor.lnum;
 			    curwin->w_cursor.col = 0;
@@ -7302,9 +7318,11 @@
 		     * Get indent and pointer to text for current line,
 		     * ignoring any jump label.	    XXX
 		     */
+		    if (!ind_js)
 		    cur_amount = skip_label(curwin->w_cursor.lnum,
 							  &l, ind_maxcomment);
-
+		    else
+			cur_amount = get_indent();
 		    /*
 		     * If this is just above the line we are indenting, and it
 		     * starts with a '{', line it up with this line.
@@ -7630,7 +7648,7 @@
 			     */
 			    curwin->w_cursor = *trypos;
 			    l = ml_get_curline();
-			    if (cin_iscase(l) || cin_isscopedecl(l))
+			    if (cin_iscase(l,FALSE) || cin_isscopedecl(l))
 			    {
 				++curwin->w_cursor.lnum;
 				curwin->w_cursor.col = 0;
@@ -7647,7 +7665,7 @@
 			 *	stat;
 			 * }
 			 */
-			iscase = (ind_keep_case_label && cin_iscase(l));
+			iscase = (ind_keep_case_label && cin_iscase(l,FALSE));
 
 			/*
 			 * Get indent and pointer to text for current line,
diff -r a8afba7027ae src/proto/misc1.pro
--- a/src/proto/misc1.pro
+++ b/src/proto/misc1.pro
@@ -76,7 +76,7 @@
 pos_T *find_start_comment __ARGS((int ind_maxcomment));
 void do_c_expr_indent __ARGS((void));
 int cin_islabel __ARGS((int ind_maxcomment));
-int cin_iscase __ARGS((char_u *s));
+int cin_iscase __ARGS((char_u *s, int));
 int cin_isscopedecl __ARGS((char_u *s));
 int get_c_indent __ARGS((void));
 int get_expr_indent __ARGS((void));
diff -r a8afba7027ae src/edit.c
--- a/src/edit.c
+++ b/src/edit.c
@@ -7499,7 +7499,7 @@
            if (try_match && keytyped == ':')
            {
                p = ml_get_curline();
-               if (cin_iscase(p) || cin_isscopedecl(p) || cin_islabel(30))
+               if (cin_iscase(p,FALSE) || cin_isscopedecl(p) || cin_islabel(30))
                    return TRUE;
                /* Need to get the line again after cin_islabel(). */
                p = ml_get_curline();
@@ -7508,7 +7508,7 @@
                        && p[curwin->w_cursor.col - 2] == ':')
                {
                    p[curwin->w_cursor.col - 1] = ' ';
-                   i = (cin_iscase(p) || cin_isscopedecl(p)
+                   i = (cin_iscase(p,FALSE) || cin_isscopedecl(p)
                                                          || cin_islabel(30));
                    p = ml_get_curline();
                    p[curwin->w_cursor.col - 1] = ':';
