--- a/conformancetest/data.js Wed Nov 09 12:23:23 2011 -0700
+++ b/conformancetest/data.js Wed Nov 09 12:42:35 2011 -0700
@@ -18239,6 +18239,206 @@
[["stylewithcss","true"],["inserttext"," "]],
"<div style=\"white-space:nowrap\"> foo []</div>",
{"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"http://a\">http://a</a> []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"http://a\">http://a</a> []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["ftp://a[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"ftp://a\">ftp://a</a> []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["ftp://a[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"ftp://a\">ftp://a</a> []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["quasit://a[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"quasit://a\">quasit://a</a> []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["quasit://a[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"quasit://a\">quasit://a</a> []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+[".x-++-.://a[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ ".<a href=\"x-++-.://a\">x-++-.://a</a> []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+[".x-++-.://a[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ ".<a href=\"x-++-.://a\">x-++-.://a</a> []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["(http://a)[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "(<a href=\"http://a\">http://a</a>) []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["(http://a)[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "(<a href=\"http://a\">http://a</a>) []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["<http://a>[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<<a href=\"http://a\">http://a</a>> []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["<http://a>[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<<a href=\"http://a\">http://a</a>> []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a![]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"http://a\">http://a</a>! []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a![]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"http://a\">http://a</a>! []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["!\"#$%&'()*+,-./:;<=>?^_`|~http://a!\"#$%&'()*+,-./:;<=>?^_`|~[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "!\"#$%&'()*+,-./:;<=>?^_`|~<a href=\"http://a!"#$%&'()*+,-./:;<=>?^_`|~\">http://a!\"#$%&'()*+,-./:;<=>?^_`|~</a> []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["!\"#$%&'()*+,-./:;<=>?^_`|~http://a!\"#$%&'()*+,-./:;<=>?^_`|~[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "!\"#$%&'()*+,-./:;<=>?^_`|~<a href=\"http://a!"#$%&'()*+,-./:;<=>?^_`|~\">http://a!\"#$%&'()*+,-./:;<=>?^_`|~</a> []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a!\"'(),-.:;<>`[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"http://a\">http://a</a>!\"'(),-.:;<>` []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a!\"'(),-.:;<>`[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"http://a\">http://a</a>!\"'(),-.:;<>` []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a#$%&*+/=?^_|~[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"http://a#$%&*+/=?^_|~\">http://a#$%&*+/=?^_|~</a> []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a#$%&*+/=?^_|~[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"http://a#$%&*+/=?^_|~\">http://a#$%&*+/=?^_|~</a> []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["mailto:a[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"mailto:a\">mailto:a</a> []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["mailto:a[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"mailto:a\">mailto:a</a> []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["a@b[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"mailto:a@b\">a@b</a> []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["a@b[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"mailto:a@b\">a@b</a> []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["a@[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "a@ []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["a@[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "a@ []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["@b[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "@b []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["@b[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "@b []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["#@x[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"mailto:#@x\">#@x</a> []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["#@x[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"mailto:#@x\">#@x</a> []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["a@.[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "a@. []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["a@.[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "a@. []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["!\"#$%&'()*+,-./:;<=>?^_`|~a@b!\"#$%&'()*+,-./:;<=>?^_`|~[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "!\"#$%&'()*+,-./:;<=><a href=\"mailto:?^_`|~a@b\">?^_`|~a@b</a>!\"#$%&'()*+,-./:;<=>?^_`|~ []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["!\"#$%&'()*+,-./:;<=>?^_`|~a@b!\"#$%&'()*+,-./:;<=>?^_`|~[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "!\"#$%&'()*+,-./:;<=><a href=\"mailto:?^_`|~a@b\">?^_`|~a@b</a>!\"#$%&'()*+,-./:;<=>?^_`|~ []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["<b>a@b</b>{}",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"mailto:a@b\"><b>a@b</b></a> []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["<b>a@b</b>{}",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"mailto:a@b\"><b>a@b</b></a> []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["<b>a</b><i>@</i><u>b</u>{}",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<b>a</b><i>@</i><u>b</u> []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["<b>a</b><i>@</i><u>b</u>{}",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<b>a</b><i>@</i><u>b</u> []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["a@b<b>[]c</b>",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"mailto:a@b\">a@b</a><b> []c</b>",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["a@b<b>[]c</b>",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"mailto:a@b\">a@b</a><b> []c</b>",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["<p>a@b</p><p>[]c</p>",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<p>a@b</p><p> []c</p>",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["<p>a@b</p><p>[]c</p>",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<p>a@b</p><p> []c</p>",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a[]",
+ [["stylewithcss","false"],["inserttext","a"]],
+ "http://aa[]",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a[]",
+ [["stylewithcss","true"],["inserttext","a"]],
+ "http://aa[]",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a[]",
+ [["stylewithcss","false"],["inserttext","\t"]],
+ "<a href=\"http://a\">http://a</a>\t[]",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a[]",
+ [["stylewithcss","true"],["inserttext","\t"]],
+ "<a href=\"http://a\">http://a</a>\t[]",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a[]",
+ [["stylewithcss","false"],["inserttext","\f"]],
+ "<a href=\"http://a\">http://a</a>\f[]",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a[]",
+ [["stylewithcss","true"],["inserttext","\f"]],
+ "<a href=\"http://a\">http://a</a>\f[]",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "http://a []",
+ {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["http://a[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "http://a []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
["foo[]",
[["stylewithcss","false"],["inserttext"," "]],
"foo []",
--- a/conformancetest/diff Wed Nov 09 12:23:23 2011 -0700
+++ b/conformancetest/diff Wed Nov 09 12:42:35 2011 -0700
@@ -1,4 +1,4 @@
-@@ -1121,11 +1121,11 @@
+@@ -1137,11 +1137,11 @@
{"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}],
["<font color=blue face=monospace><b>foo</b></font>[bar]",
[["stylewithcss","false"],["bold",""]],
@@ -12,7 +12,7 @@
{"stylewithcss":[false,false,"",false,true,""],"bold":[false,false,"",false,true,""]}],
["foo<span style=\"font-weight: normal\"><b>{bar}</b></span>baz",
[["stylewithcss","false"],["bold",""]],
-@@ -1737,11 +1737,11 @@
+@@ -1761,11 +1761,11 @@
{"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}],
["foö̧[]bar",
[["stylewithcss","false"],["delete",""]],
@@ -26,7 +26,7 @@
{"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}],
["ö[]bar",
[["stylewithcss","false"],["delete",""]],
-@@ -1761,11 +1761,11 @@
+@@ -1785,11 +1785,11 @@
{"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}],
["ö̧[]bar",
[["stylewithcss","false"],["delete",""]],
@@ -40,7 +40,7 @@
{"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}],
["שָׁ[]לוֹם",
[["stylewithcss","false"],["delete",""]],
-@@ -1777,11 +1777,11 @@
+@@ -1801,11 +1801,11 @@
{"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}],
["שָׁלוֹ[]ם",
[["stylewithcss","false"],["delete",""]],
@@ -54,7 +54,7 @@
{"stylewithcss":[false,false,"",false,true,""],"delete":[false,false,"",false,false,""]}],
["<p>foo</p><p>[]bar</p>",
[["stylewithcss","false"],["delete",""]],
-@@ -5650,11 +5650,11 @@
+@@ -5954,11 +5954,11 @@
["foo[bar]baz",
[["stylewithcss","false"],["forecolor","rgba(0, 0, 255, 0.0)"]],
"foo<span style=\"color:rgba(0, 0, 0, 0)\">[bar]</span>baz",
@@ -68,7 +68,7 @@
["foo[bar]baz",
[["stylewithcss","false"],["forecolor","rgb(15, -10, 375)"]],
"foo<font color=\"#0f00ff\">[bar]</font>baz",
-@@ -5946,11 +5946,11 @@
+@@ -6250,11 +6250,11 @@
["<span style=\"color: rgba(0, 0, 255, 0.0)\">[foo]</span>",
[["stylewithcss","false"],["forecolor","#0000FF"]],
"<font color=\"#0000ff\">[foo]</font>",
@@ -82,7 +82,7 @@
["<span style=\"color: rgb(15, -10, 375)\">[foo]</span>",
[["stylewithcss","false"],["forecolor","#0000FF"]],
"<font color=\"#0000ff\">[foo]</font>",
-@@ -8081,11 +8081,11 @@
+@@ -8385,11 +8385,11 @@
{"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}],
["שָׁל[]וֹם",
[["stylewithcss","false"],["forwarddelete",""]],
@@ -96,7 +96,7 @@
{"stylewithcss":[false,false,"",false,true,""],"forwarddelete":[false,false,"",false,false,""]}],
["<p>foo[]</p><p>bar</p>",
[["stylewithcss","false"],["forwarddelete",""]],
-@@ -12063,6 +12063,14 @@
+@@ -12639,6 +12639,14 @@
[["stylewithcss","true"],["inserthorizontalrule",""]],
"<b>foo</b><hr>{}<b>baz</b>",
{"stylewithcss":[false,false,"",false,true,""],"inserthorizontalrule":[false,false,"",false,false,""]}],
@@ -111,7 +111,7 @@
["<bdo dir=rtl>foo[bar]baz</bdo>",
[["stylewithcss","false"],["inserthorizontalrule",""]],
"<bdo dir=\"rtl\">foo</bdo><hr>{}<bdo dir=\"rtl\">baz</bdo>",
-@@ -12751,18 +12759,10 @@
+@@ -13327,18 +13335,10 @@
[["stylewithcss","true"],["inserthtml","abc"]],
"<xmp>fabc{}o</xmp>",
{"stylewithcss":[false,false,"",false,true,""],"inserthtml":[false,false,"",false,false,""]}],
@@ -131,7 +131,64 @@
["<script>f[o]o</script>bar",
[["stylewithcss","true"],["inserthtml","abc"]],
"<script>fabc{}o</script>bar",
-@@ -19849,11 +19849,11 @@
+@@ -18287,34 +18287,18 @@
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"http://a\">http://a</a>! []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+-["!\"#$%&'()*+,-./:;<=>?^_`|~http://a!\"#$%&'()*+,-./:;<=>?^_`|~[]",
+- [["stylewithcss","false"],["inserttext"," "]],
+- "!\"#$%&'()*+,-./:;<=>?^_`|~<a href=\"http://a!"#$%&'()*+,-./:;<=>?^_`|~\">http://a!\"#$%&'()*+,-./:;<=>?^_`|~</a> []",
+- {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+-["!\"#$%&'()*+,-./:;<=>?^_`|~http://a!\"#$%&'()*+,-./:;<=>?^_`|~[]",
+- [["stylewithcss","true"],["inserttext"," "]],
+- "!\"#$%&'()*+,-./:;<=>?^_`|~<a href=\"http://a!"#$%&'()*+,-./:;<=>?^_`|~\">http://a!\"#$%&'()*+,-./:;<=>?^_`|~</a> []",
+- {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+ ["http://a!\"'(),-.:;<>`[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"http://a\">http://a</a>!\"'(),-.:;<>` []",
+- {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
++ {"stylewithcss":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+ ["http://a!\"'(),-.:;<>`[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"http://a\">http://a</a>!\"'(),-.:;<>` []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+-["http://a#$%&*+/=?^_|~[]",
+- [["stylewithcss","false"],["inserttext"," "]],
+- "<a href=\"http://a#$%&*+/=?^_|~\">http://a#$%&*+/=?^_|~</a> []",
+- {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+-["http://a#$%&*+/=?^_|~[]",
+- [["stylewithcss","true"],["inserttext"," "]],
+- "<a href=\"http://a#$%&*+/=?^_|~\">http://a#$%&*+/=?^_|~</a> []",
+- {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+ ["mailto:a[]",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"mailto:a\">mailto:a</a> []",
+- {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
++ {"stylewithcss":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+ ["mailto:a[]",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"mailto:a\">mailto:a</a> []",
+@@ -18359,18 +18343,10 @@
+ [["stylewithcss","true"],["inserttext"," "]],
+ "a@. []",
+ {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+-["!\"#$%&'()*+,-./:;<=>?^_`|~a@b!\"#$%&'()*+,-./:;<=>?^_`|~[]",
+- [["stylewithcss","false"],["inserttext"," "]],
+- "!\"#$%&'()*+,-./:;<=><a href=\"mailto:?^_`|~a@b\">?^_`|~a@b</a>!\"#$%&'()*+,-./:;<=>?^_`|~ []",
+- {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+-["!\"#$%&'()*+,-./:;<=>?^_`|~a@b!\"#$%&'()*+,-./:;<=>?^_`|~[]",
+- [["stylewithcss","true"],["inserttext"," "]],
+- "!\"#$%&'()*+,-./:;<=><a href=\"mailto:?^_`|~a@b\">?^_`|~a@b</a>!\"#$%&'()*+,-./:;<=>?^_`|~ []",
+- {"stylewithcss":[false,false,"",false,true,""],"inserttext":[false,false,"",false,false,""]}],
+ ["<b>a@b</b>{}",
+ [["stylewithcss","false"],["inserttext"," "]],
+ "<a href=\"mailto:a@b\"><b>a@b</b></a> []",
+- {"stylewithcss":[false,true,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
++ {"stylewithcss":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+ ["<b>a@b</b>{}",
+ [["stylewithcss","true"],["inserttext"," "]],
+ "<a href=\"mailto:a@b\"><b>a@b</b></a> []",
+@@ -20601,11 +20577,11 @@
{"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}],
["fo[o<span style=font-style:oblique>b]ar</span>baz",
[["stylewithcss","false"],["italic",""]],
@@ -145,7 +202,7 @@
{"stylewithcss":[false,false,"",false,true,""],"italic":[true,false,"",false,true,""]}],
["<span style=font-style:italic>fo[o</span><span style=font-style:oblique>b]ar</span>",
[["stylewithcss","false"],["italic",""]],
-@@ -22889,35 +22889,35 @@
+@@ -23641,35 +23617,35 @@
{"stylewithcss":[false,false,"",false,true,""],"outdent":[false,false,"",false,false,""]}],
["<blockquote class=\"webkit-indent-blockquote\" style=\"margin: 0 0 0 40px; border: none; padding: 0px;\"><p>foo[bar]</p><p>baz</p></blockquote><p>extra",
[["stylewithcss","false"],["outdent",""]],
--- a/editing.html Wed Nov 09 12:23:23 2011 -0700
+++ b/editing.html Wed Nov 09 12:42:35 2011 -0700
@@ -173,6 +173,7 @@
<li><a href=#indenting-and-outdenting>Indenting and outdenting</a></li>
<li><a href=#toggling-lists>Toggling lists</a></li>
<li><a href=#justifying-the-selection>Justifying the selection</a></li>
+ <li><a href=#automatic-linking>Automatic linking</a></li>
<li><a href=#the-delete-command>The <code title="">delete</code> command</a></li>
<li><a href=#the-formatblock-command>The <code title="">formatBlock</code> command</a></li>
<li><a href=#the-forwarddelete-command>The <code title="">forwardDelete</code> command</a></li>
@@ -7468,6 +7469,131 @@
</ol>
+<h3 id=automatic-linking>Automatic linking</h3>
+
+<p class=comments><a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=13807">Bug 13807</a>.
+
+<p class=note>When the user inserts whitespace immediately following something
+that looks like a URL or e-mail address, we automatically run <a href=#the-createlink-command>the <code title="">createLink</code> command</a> on it.
+
+<p>An <dfn id=autolinkable-url>autolinkable URL</dfn> is a string of the following form:
+
+<ol>
+ <li>
+ <p class=comments>IE9 and LibreOffice 3.3.4 both have a whitelist of URL
+ schemes. That would be complicated and involve political decisions, so
+ instead, we'll just accept anything that looks like a hierarchical URL
+ scheme. Google Docs is similar (as of November 9, 2011), but it's too lax,
+ and allows characters in the scheme that can't be in a scheme. For
+ non-hierarchical schemes, we just whitelist mailto:, since it's the only
+ common one that makes sense to autolink.
+
+ <p>Either a string matching the <var title="">scheme</var> pattern from <a href=http://tools.ietf.org/html/rfc3986#section-3.1>RFC 3986 section 3.1</a>
+ followed by the literal string <code title="">://</code>, or the literal string
+ <code title="">mailto:</code>; followed by
+
+ <li>
+ <p class=comments>We don't try to enforce that the URL is anything resembling
+ valid per spec. Too complicated for not enough gain.
+
+ <p>Zero or more characters other than <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#space-character title="space character">space characters</a>; followed by
+
+ <li>
+ <div class=comments>
+ <p>If the user types a URL followed by some punctuation, we still want to
+ autolink, but we don't want to include the punctuation if it's probably not
+ meant as part of the URL.
+
+ <p>IE9 excludes <code title="">!#&()*+,-.:;<=?@[]^_`{|}~</code> as
+ trailing characters from both URLs and e-mails. A trailing <code title="">"</code> or
+ <code title="">></code> will prevent autolinking, and a trailing <code title="">$%'/\</code> is
+ included in the link.
+
+ <p>LibreOffice 3.3.4 excludes trailing <code title="">!”#'()*+,.:;<=>?[\]^_`{|}~</code>,
+ and prevents autolinking on <code title="">$%&-@</code>. It includes a trailing
+ <code title="">/</code> in URLs, but it inhibits linking for e-mails.
+
+ <p>Google Docs (as of November 9, 2011) is complicated. Trailing
+ <code title="">”’,-.</code> always prevents autolinking of a URL, and trailing
+ <code title="">#%/?_</code> is always included in a URL. Trailing <code title="">!&=$()*+:;<>@[\]^`{|}~</code> prevent autolinking if there's no
+ <code title="">?</code> before them, but are included in the URL if there is a <code title="">?</code>.
+ For e-mails, <code title="">_</code> is included, and everything else prevents
+ autolinking.
+
+ <p>None of these behaviors makes maximal sense. We should exclude characters
+ if they're more likely as delimiters than actual trailing characters; include
+ them if they're more likely as actual trailing characters; and prevent
+ autolinking if their presence suggests that we're not actually looking at a
+ link or e-mail address. The lists I made up for URLs are: exclude trailing
+ <code title="">!"'(),-.:;<>[]`{}</code>, include anything else. For e-mail,
+ exclude anything at all.
+ </div>
+
+ <p>A character that is not one of the ASCII characters <code title="">!"'(),-.:;<>[]`{}</code>.
+</ol>
+
+<p>To <dfn id=autolink>autolink</dfn> (<var title="">node</var>, <var title="">end offset</var>):
+
+<ol>
+ <li>While (<var title="">node</var>, <var title="">end offset</var>)'s <a href=#previous-equivalent-point>previous
+ equivalent point</a> is not null, set it to its <a href=#previous-equivalent-point>previous equivalent
+ point</a>.
+
+ <li>If <var title="">node</var> is not a <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node, or has an <code class=external data-anolis-spec=html title="the a element"><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#the-a-element>a</a></code> <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-ancestor title=concept-tree-ancestor>ancestor</a>,
+ do nothing and abort these steps.
+
+ <li>Let <var title="">search</var> be the largest substring of <var title="">node</var>'s
+ <code class=external data-anolis-spec=dom title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> whose end is <var title="">end offset</var> and that contains no
+ <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#space-character title="space character">space characters</a>.
+
+ <li>If some substring of <var title="">search</var> is an <a href=#autolinkable-url>autolinkable
+ URL</a>:
+
+ <ol>
+ <li>While there is no substring of <var title="">node</var>'s <code class=external data-anolis-spec=dom title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> ending at
+ <var title="">end offset</var> that is an <a href=#autolinkable-url>autolinkable URL</a>, decrement
+ <var title="">end offset</var>.
+
+ <li>Let <var title="">start offset</var> be the start index of the longest substring
+ of <var title="">node</var>'s <code class=external data-anolis-spec=dom title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> that is an <a href=#autolinkable-url>autolinkable URL</a>
+ ending at <var title="">end offset</var>.
+
+ <li>Let <var title="">href</var> be the substring of <var title="">node</var>'s <code class=external data-anolis-spec=dom title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code>
+ starting at <var title="">start offset</var> and ending at <var title="">end offset</var>.
+ </ol>
+
+ <li>Otherwise, if some substring of <var title="">search</var> is a <a class=external data-anolis-spec=html href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address>valid e-mail address</a>:
+
+ <ol>
+ <li>While there is no substring of <var title="">node</var>'s <code class=external data-anolis-spec=dom title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> ending at
+ <var title="">end offset</var> that is a <a class=external data-anolis-spec=html href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address>valid e-mail
+ address</a>, decrement <var title="">end offset</var>.
+
+ <li>Let <var title="">start offset</var> be the start index of the longest substring
+ of <var title="">node</var>'s <code class=external data-anolis-spec=dom title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> that is a <a class=external data-anolis-spec=html href=http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address>valid
+ e-mail address</a> ending at <var title="">end offset</var>.
+
+ <li>Let <var title="">href</var> be "mailto:" concatenated with the substring of
+ <var title="">node</var>'s <code class=external data-anolis-spec=dom title=dom-CharacterData-data><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-characterdata-data>data</a></code> starting at <var title="">start offset</var> and ending
+ at <var title="">end offset</var>.
+ </ol>
+
+ <li>Otherwise, do nothing and abort these steps.
+
+ <li>Let <var title="">original range</var> be the <a href=#active-range>active range</a>.
+
+ <li>Create a new <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> with <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-start title=concept-range-start>start</a> (<var title="">node</var>, <var title="">start
+ offset</var>) and <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-end title=concept-range-end>end</a> (<var title="">node</var>, <var title="">end offset</var>), and
+ set the <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#context-object>context object</a>'s <a href=#concept-selection title=concept-selection>selection</a>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> to it.
+
+ <li>Call <code title=execCommand()><a href=#execcommand()>execCommand("createLink", false, <var title="">href</var>)</a></code> on the
+ <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#context-object>context object</a>.
+
+ <li>Set the <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#context-object>context object</a>'s <a href=#concept-selection title=concept-selection>selection</a>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> to <var title="">original
+ range</var>.
+</ol>
+
+
<h3 id=the-delete-command><dfn>The <code title="">delete</code> command</dfn></h3>
<div class=note>
@@ -9529,8 +9655,8 @@
<p>If <var title="">node</var> has only one <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a>, which is a <a href=#collapsed-line-break>collapsed
line break</a>, remove its <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> from it.
- <li>Let <var title="">text</var> be the result of calling <code class=external data-anolis-spec=domcore title=dom-Document-createTextNode><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createtextnode>createTextNode(<var title="">value</var>)</a></code> on
- the <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#context-object>context object</a>.
+ <li>Let <var title="">text</var> be the result of calling
+ <code class=external data-anolis-spec=dom title=dom-Document-createTextNode><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-document-createtextnode>createTextNode(<var title="">value</var>)</a></code> on the <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#context-object>context object</a>.
<li>Call <code class=external data-anolis-spec=dom title=dom-Range-insertNode><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-range-insertnode>insertNode(<var title="">text</var>)</a></code> on the <a href=#active-range>active range</a>.
@@ -9549,6 +9675,9 @@
<li><a href=#canonicalize-whitespace>Canonicalize whitespace</a> at the <a href=#active-range>active range</a>'s
<a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-end title=concept-range-end>end</a>, with <var title="">fix collapsed space</var> false.
+ <li>If <var title="">value</var> is a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#space-character title="space character">space character</a>, <a href=#autolink>autolink</a> the
+ <a href=#active-range>active range</a>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-start title=concept-range-start>start</a>.
+
<li>Call <code title=dom-Selection-collapseToEnd><a href=#dom-selection-collapsetoend>collapseToEnd()</a></code> on the <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#context-object>context object</a>'s <a href=#concept-selection title=concept-selection>selection</a>.
</ol>
--- a/implementation.js Wed Nov 09 12:23:23 2011 -0700
+++ b/implementation.js Wed Nov 09 12:42:35 2011 -0700
@@ -6025,6 +6025,112 @@
//@}
+///// Automatic linking /////
+//@{
+// "An autolinkable URL is a string of the following form:"
+var autolinkableUrlRegexp =
+ // "Either a string matching the scheme pattern from RFC 3986 section 3.1
+ // followed by the literal string ://, or the literal string mailto:;
+ // followed by"
+ //
+ // From the RFC: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+ "([a-zA-Z][a-zA-Z0-9+.-]*://|mailto:)"
+ // "Zero or more characters other than space characters; followed by"
+ + "[^ \t\n\f\r]*"
+ // "A character that is not one of the ASCII characters !"'(),-.:;<>[]`{}."
+ + "[^!\"'(),\\-.:;<>[\\]`{}]";
+
+// "A valid e-mail address is a string that matches the ABNF production 1*(
+// atext / "." ) "@" ldh-str *( "." ldh-str ) where atext is defined in RFC
+// 5322 section 3.2.3, and ldh-str is defined in RFC 1034 section 3.5."
+//
+// atext: ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" /
+// "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~"
+//
+//<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
+//<let-dig-hyp> ::= <let-dig> | "-"
+//<let-dig> ::= <letter> | <digit>
+var validEmailRegexp =
+ "[a-zA-Z0-9!#$%&'*+\\-/=?^_`{|}~.]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*";
+
+function autolink(node, endOffset) {
+ // "While (node, end offset)'s previous equivalent point is not null, set
+ // it to its previous equivalent point."
+ while (getPreviousEquivalentPoint(node, endOffset)) {
+ var prev = getPreviousEquivalentPoint(node, endOffset);
+ node = prev[0];
+ endOffset = prev[1];
+ }
+
+ // "If node is not a Text node, or has an a ancestor, do nothing and abort
+ // these steps."
+ if (node.nodeType != Node.TEXT_NODE
+ || getAncestors(node).some(function(ancestor) { return isHtmlElement(ancestor, "a") })) {
+ return;
+ }
+
+ // "Let search be the largest substring of node's data whose end is end
+ // offset and that contains no space characters."
+ var search = /[^ \t\n\f\r]*$/.exec(node.substringData(0, endOffset))[0];
+
+ // "If some substring of search is an autolinkable URL:"
+ if (new RegExp(autolinkableUrlRegexp).test(search)) {
+ // "While there is no substring of node's data ending at end offset
+ // that is an autolinkable URL, decrement end offset."
+ while (!(new RegExp(autolinkableUrlRegexp + "$").test(node.substringData(0, endOffset)))) {
+ endOffset--;
+ }
+
+ // "Let start offset be the start index of the longest substring of
+ // node's data that is an autolinkable URL ending at end offset."
+ var startOffset = new RegExp(autolinkableUrlRegexp + "$").exec(node.substringData(0, endOffset)).index;
+
+ // "Let href be the substring of node's data starting at start offset
+ // and ending at end offset."
+ var href = node.substringData(startOffset, endOffset - startOffset);
+
+ // "Otherwise, if some substring of search is a valid e-mail address:"
+ } else if (new RegExp(validEmailRegexp).test(search)) {
+ // "While there is no substring of node's data ending at end offset
+ // that is a valid e-mail address, decrement end offset."
+ while (!(new RegExp(validEmailRegexp + "$").test(node.substringData(0, endOffset)))) {
+ endOffset--;
+ }
+
+ // "Let start offset be the start index of the longest substring of
+ // node's data that is a valid e-mail address ending at end offset."
+ var startOffset = new RegExp(validEmailRegexp + "$").exec(node.substringData(0, endOffset)).index;
+
+ // "Let href be "mailto:" concatenated with the substring of node's
+ // data starting at start offset and ending at end offset."
+ var href = "mailto:" + node.substringData(startOffset, endOffset - startOffset);
+
+ // "Otherwise, do nothing and abort these steps."
+ } else {
+ return;
+ }
+
+ // "Let original range be the active range."
+ var originalRange = getActiveRange();
+
+ // "Create a new range with start (node, start offset) and end (node, end
+ // offset), and set the context object's selection's range to it."
+ var newRange = document.createRange();
+ newRange.setStart(node, startOffset);
+ newRange.setEnd(node, endOffset);
+ getSelection().removeAllRanges();
+ getSelection().addRange(newRange);
+ globalRange = newRange;
+
+ // "Call execCommand("createLink", false, href) on the context object."
+ myExecCommand("createLink", false, href);
+
+ // "Set the context object's selection's range to original range."
+ getSelection().removeAllRanges();
+ getSelection().addRange(originalRange);
+ globalRange = originalRange;
+}
+//@}
///// The delete command /////
//@{
commands["delete"] = {
@@ -7761,6 +7867,11 @@
// collapsed space false."
canonicalizeWhitespace(getActiveRange().endContainer, getActiveRange().endOffset, false);
+ // "If value is a space character, autolink the active range's start."
+ if (/^[ \t\n\f\r]$/.test(value)) {
+ autolink(getActiveRange().startContainer, getActiveRange().startOffset);
+ }
+
// "Call collapseToEnd() on the context object's Selection."
//
// Work around WebKit bug: sometimes it blows up the selection and
--- a/preprocess Wed Nov 09 12:23:23 2011 -0700
+++ b/preprocess Wed Nov 09 12:42:35 2011 -0700
@@ -150,6 +150,7 @@
'addrange': '<code title=dom-Selection-addRange>addRange(\\1)</code>',
'appendchild': '<code data-anolis-spec=dom title=dom-Node-appendChild>appendChild(\\1)</code>',
'createelement': '<code data-anolis-spec=dom title=dom-Document-createElement>createElement(\\1)</code>',
+ 'createtextnode': '<code data-anolis-spec=dom title=dom-Document-createTextNode>createTextNode(\\1)</code>',
'deletedata': '<code data-anolis-spec=dom title=dom-CharacterData-deleteData>deleteData(\\1)</code>',
'execcommand': '<code title=execCommand()>execCommand(\\1)</code>',
'extend': '<code title=dom-Selection-extend>extend(\\1)</code>',
--- a/source.html Wed Nov 09 12:23:23 2011 -0700
+++ b/source.html Wed Nov 09 12:42:35 2011 -0700
@@ -7548,6 +7548,137 @@
</ol>
<!-- @} -->
+<h3>Automatic linking</h3>
+<!-- @{ -->
+<p class=comments><a
+href=http://www.w3.org/Bugs/Public/show_bug.cgi?id=13807>Bug 13807</a>.
+
+<p class=note>When the user inserts whitespace immediately following something
+that looks like a URL or e-mail address, we automatically run <span>the <code
+title>createLink</code> command</span> on it.
+
+<p>An <dfn>autolinkable URL</dfn> is a string of the following form:
+
+<ol>
+ <li>
+ <p class=comments>IE9 and LibreOffice 3.3.4 both have a whitelist of URL
+ schemes. That would be complicated and involve political decisions, so
+ instead, we'll just accept anything that looks like a hierarchical URL
+ scheme. Google Docs is similar (as of November 9, 2011), but it's too lax,
+ and allows characters in the scheme that can't be in a scheme. For
+ non-hierarchical schemes, we just whitelist mailto:, since it's the only
+ common one that makes sense to autolink.
+
+ <p>Either a string matching the <var>scheme</var> pattern from <a
+ href=http://tools.ietf.org/html/rfc3986#section-3.1>RFC 3986 section 3.1</a>
+ followed by the literal string {{code|://}}, or the literal string
+ {{code|mailto:}}; followed by
+
+ <li>
+ <p class=comments>We don't try to enforce that the URL is anything resembling
+ valid per spec. Too complicated for not enough gain.
+
+ <p>Zero or more characters other than [[spacecharacters]]; followed by
+
+ <li>
+ <div class=comments>
+ <p>If the user types a URL followed by some punctuation, we still want to
+ autolink, but we don't want to include the punctuation if it's probably not
+ meant as part of the URL.
+
+ <p>IE9 excludes <code title>!#&()*+,-.:;<=?@[]^_`{|}~</code> as
+ trailing characters from both URLs and e-mails. A trailing {{code|"}} or
+ {{code|>}} will prevent autolinking, and a trailing {{code|$%'/\}} is
+ included in the link.
+
+ <p>LibreOffice 3.3.4 excludes trailing {{code|!”#'()*+,.:;<=>?[\]^_`{|}~}},
+ and prevents autolinking on {{code|$%&-@ }}. It includes a trailing
+ {{code|/}} in URLs, but it inhibits linking for e-mails.
+
+ <p>Google Docs (as of November 9, 2011) is complicated. Trailing
+ {{code|”’,-.}} always prevents autolinking of a URL, and trailing
+ {{code|#%/?_}} is always included in a URL. Trailing <code
+ title>!&=$()*+:;<>@[\]^`{|}~</code> prevent autolinking if there's no
+ {{code|?}} before them, but are included in the URL if there is a {{code|?}}.
+ For e-mails, {{code|_}} is included, and everything else prevents
+ autolinking.
+
+ <p>None of these behaviors makes maximal sense. We should exclude characters
+ if they're more likely as delimiters than actual trailing characters; include
+ them if they're more likely as actual trailing characters; and prevent
+ autolinking if their presence suggests that we're not actually looking at a
+ link or e-mail address. The lists I made up for URLs are: exclude trailing
+ <code title>!"'(),-.:;<>[]`{}</code>, include anything else. For e-mail,
+ exclude anything at all.
+ </div>
+
+ <p>A character that is not one of the ASCII characters <code
+ title>!"'(),-.:;<>[]`{}</code>.
+</ol>
+
+<p>To <dfn>autolink</dfn> (<var>node</var>, <var>end offset</var>):
+
+<ol>
+ <li>While (<var>node</var>, <var>end offset</var>)'s <span>previous
+ equivalent point</span> is not null, set it to its <span>previous equivalent
+ point</span>.
+
+ <li>If <var>node</var> is not a [[text]] node, or has an [[a]] [[ancestor]],
+ do nothing and abort these steps.
+
+ <li>Let <var>search</var> be the largest substring of <var>node</var>'s
+ [[cddata]] whose end is <var>end offset</var> and that contains no
+ [[spacecharacters]].
+
+ <li>If some substring of <var>search</var> is an <span>autolinkable
+ URL</span>:
+
+ <ol>
+ <li>While there is no substring of <var>node</var>'s [[cddata]] ending at
+ <var>end offset</var> that is an <span>autolinkable URL</span>, decrement
+ <var>end offset</var>.
+
+ <li>Let <var>start offset</var> be the start index of the longest substring
+ of <var>node</var>'s [[cddata]] that is an <span>autolinkable URL</span>
+ ending at <var>end offset</var>.
+
+ <li>Let <var>href</var> be the substring of <var>node</var>'s [[cddata]]
+ starting at <var>start offset</var> and ending at <var>end offset</var>.
+ </ol>
+
+ <li>Otherwise, if some substring of <var>search</var> is a <span
+ data-anolis-spec=html>valid e-mail address</span>:
+
+ <ol>
+ <li>While there is no substring of <var>node</var>'s [[cddata]] ending at
+ <var>end offset</var> that is a <span data-anolis-spec=html>valid e-mail
+ address</span>, decrement <var>end offset</var>.
+
+ <li>Let <var>start offset</var> be the start index of the longest substring
+ of <var>node</var>'s [[cddata]] that is a <span data-anolis-spec=html>valid
+ e-mail address</span> ending at <var>end offset</var>.
+
+ <li>Let <var>href</var> be "mailto:" concatenated with the substring of
+ <var>node</var>'s [[cddata]] starting at <var>start offset</var> and ending
+ at <var>end offset</var>.
+ </ol>
+
+ <li>Otherwise, do nothing and abort these steps.
+
+ <li>Let <var>original range</var> be the <span>active range</span>.
+
+ <li>Create a new [[range]] with [[rangestart]] (<var>node</var>, <var>start
+ offset</var>) and [[rangeend]] (<var>node</var>, <var>end offset</var>), and
+ set the [[contextobject]]'s [[selection]]'s [[range]] to it.
+
+ <li>Call [[execcommand|"createLink", false, <var>href</var>]] on the
+ [[contextobject]].
+
+ <li>Set the [[contextobject]]'s [[selection]]'s [[range]] to <var>original
+ range</var>.
+</ol>
+
+<!-- @} -->
<h3><dfn>The <code title>delete</code> command</dfn></h3>
<!-- @{ -->
<div class=note>
@@ -9625,10 +9756,8 @@
<p>If <var>node</var> has only one [[child]], which is a <span>collapsed
line break</span>, remove its [[child]] from it.
- <li>Let <var>text</var> be the result of calling <code
- data-anolis-spec=domcore
- title=dom-Document-createTextNode>createTextNode(<var>value</var>)</code> on
- the [[contextobject]].
+ <li>Let <var>text</var> be the result of calling
+ [[createtextnode|<var>value</var>]] on the [[contextobject]].
<li>Call [[insertnode|<var>text</var>]] on the <span>active range</span>.
@@ -9647,6 +9776,9 @@
<li><span>Canonicalize whitespace</span> at the <span>active range</span>'s
[[rangeend]], with <var>fix collapsed space</var> false.
+ <li>If <var>value</var> is a [[spacecharacter]], <span>autolink</span> the
+ <span>active range</span>'s [[rangestart]].
+
<li>Call [[collapsetoend]] on the [[contextobject]]'s [[selection]].
</ol>
--- a/tests.js Wed Nov 09 12:23:23 2011 -0700
+++ b/tests.js Wed Nov 09 12:42:35 2011 -0700
@@ -2580,6 +2580,40 @@
// End whitespace tests
+ // Autolinking tests
+ [' ', 'http://a[]'],
+ [' ', 'ftp://a[]'],
+ [' ', 'quasit://a[]'],
+ [' ', '.x-++-.://a[]'],
+ [' ', '(http://a)[]'],
+ [' ', '<http://a>[]'],
+ // http://www.w3.org/Bugs/Public/show_bug.cgi?id=14744
+ ['! ', '[http://a][]'],
+ ['! ', '{http://a}[]'],
+ [' ', 'http://a![]'],
+ [' ', '!"#$%&\'()*+,-./:;<=>?\^_`|~http://a!"#$%&\'()*+,-./:;<=>?\^_`|~[]'],
+ [' ', 'http://a!"\'(),-.:;<>`[]'],
+ [' ', 'http://a#$%&*+/=?\^_|~[]'],
+ [' ', 'mailto:a[]'],
+ [' ', 'a@b[]'],
+ [' ', 'a@[]'],
+ [' ', '@b[]'],
+ [' ', '#@x[]'],
+ [' ', 'a@.[]'],
+ [' ', '!"#$%&\'()*+,-./:;<=>?\^_`|~a@b!"#$%&\'()*+,-./:;<=>?\^_`|~[]'],
+ [' ', '<b>a@b</b>{}'],
+ [' ', '<b>a</b><i>@</i><u>b</u>{}'],
+ [' ', 'a@b<b>[]c</b>'],
+ [' ', '<p>a@b</p><p>[]c</p>'],
+ ['a', 'http://a[]'],
+ ['\t', 'http://a[]'],
+ // http://www.w3.org/Bugs/Public/show_bug.cgi?id=14254
+ ['!\r', 'http://a[]'],
+ // http://www.w3.org/Bugs/Public/show_bug.cgi?id=14745
+ ['!\n', 'http://a[]'],
+ ['\f', 'http://a[]'],
+ ['\u00A0', 'http://a[]'],
+
[' ', 'foo[]'],
'foo[]bar',