Mercurial > urweb
comparison lib/js/urweb.js @ 1803:d2383ffc18ab
Back out last change and pursue a different fix, based on explicitly aborting script execution at times when we don't expect scripts to run
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Fri, 03 Aug 2012 12:39:04 -0400 |
parents | e3ec868567ce |
children | 9913c81bdbef |
comparison
equal
deleted
inserted
replaced
1802:e3ec868567ce | 1803:d2383ffc18ab |
---|---|
689 pos = pos.parentNode; | 689 pos = pos.parentNode; |
690 | 690 |
691 return pos; | 691 return pos; |
692 } | 692 } |
693 | 693 |
694 var thisScript = null; | |
695 | |
694 function parent() { | 696 function parent() { |
695 return thisScript ? thisScript.parentNode : lastParent(); | 697 return thisScript ? thisScript.parentNode : lastParent(); |
696 } | 698 } |
697 | 699 |
698 function addNode(node) { | 700 function addNode(node) { |
701 thisScript.parentNode.replaceChild(node, thisScript); | 703 thisScript.parentNode.replaceChild(node, thisScript); |
702 } else | 704 } else |
703 lastParent().appendChild(node); | 705 lastParent().appendChild(node); |
704 } | 706 } |
705 | 707 |
706 var thisScript = null; | |
707 | |
708 function runScripts(node) { | 708 function runScripts(node) { |
709 if (node.getElementsByTagName) { | 709 if (node.tagName == "SCRIPT") { |
710 var savedScript = thisScript; | |
711 thisScript = node; | |
712 | |
713 try { | |
714 eval(thisScript.text); | |
715 } catch (v) { | |
716 doExn(v); | |
717 } | |
718 if (thisScript.parentNode) | |
719 thisScript.parentNode.removeChild(thisScript); | |
720 | |
721 thisScript = savedScript; | |
722 } else if (node.getElementsByTagName) { | |
710 var savedScript = thisScript; | 723 var savedScript = thisScript; |
711 | 724 |
712 var scripts = node.getElementsByTagName("script"), scriptsCopy = []; | 725 var scripts = node.getElementsByTagName("script"), scriptsCopy = []; |
713 var len = scripts.length; | 726 var len = scripts.length; |
714 for (var i = 0; i < len; ++i) | 727 for (var i = 0; i < len; ++i) |
745 function normalizeTable(table) { | 758 function normalizeTable(table) { |
746 var orig = table; | 759 var orig = table; |
747 | 760 |
748 var script, next; | 761 var script, next; |
749 | 762 |
750 while (table.tagName != "TABLE") | 763 while (table && table.tagName != "TABLE") |
751 table = table.parentNode; | 764 table = table.parentNode; |
752 | 765 |
753 for (var tbody = table.firstChild; tbody; tbody = tbody.nextSibling) { | 766 for (var tbody = table.firstChild; tbody; tbody = tbody.nextSibling) { |
754 if (tbody.tagName == "TBODY") { | 767 if (tbody.tagName == "TBODY") { |
755 var firstChild = tbody.firstChild; | 768 var firstChild = tbody.firstChild; |
774 tbody.appendChild(script); | 787 tbody.appendChild(script); |
775 } | 788 } |
776 table.appendChild(tbody); | 789 table.appendChild(tbody); |
777 } | 790 } |
778 | 791 |
792 var suspendScripts = false; | |
793 | |
779 function dyn(pnode, s) { | 794 function dyn(pnode, s) { |
795 if (suspendScripts) | |
796 return; | |
797 | |
780 var x = document.createElement("script"); | 798 var x = document.createElement("script"); |
781 x.dead = false; | 799 x.dead = false; |
782 x.signal = s; | 800 x.signal = s; |
783 x.sources = null; | 801 x.sources = null; |
784 x.closures = null; | 802 x.closures = null; |
812 | 830 |
813 if (pnode == "table") { | 831 if (pnode == "table") { |
814 normalizeTable(x.parentNode); | 832 normalizeTable(x.parentNode); |
815 | 833 |
816 var dummy = document.createElement("body"); | 834 var dummy = document.createElement("body"); |
817 dummy.innerHTML = "<table>" + html + "</table>"; | 835 suspendScripts = true; |
818 runScripts(dummy); | 836 try { |
837 dummy.innerHTML = "<table>" + html + "</table>"; | |
838 } catch (e) { | |
839 suspendScripts = false; | |
840 throw e; | |
841 } | |
842 | |
819 var table = x.parentNode; | 843 var table = x.parentNode; |
820 | 844 |
821 if (table) { | 845 if (table) { |
822 firstChild = null; | 846 firstChild = null; |
823 var tbody; | 847 var tbody; |
841 firstChild = document.createElement("script"); | 865 firstChild = document.createElement("script"); |
842 table.insertBefore(firstChild, x); | 866 table.insertBefore(firstChild, x); |
843 for (var node = tbody.firstChild; node; node = next) { | 867 for (var node = tbody.firstChild; node; node = next) { |
844 next = node.nextSibling; | 868 next = node.nextSibling; |
845 table.insertBefore(node, x); | 869 table.insertBefore(node, x); |
870 suspendScripts = false; | |
871 runScripts(node); | |
872 suspendScripts = true; | |
846 } | 873 } |
847 } | 874 } |
875 | |
876 suspendScripts = false; | |
848 } else if (pnode == "tr") { | 877 } else if (pnode == "tr") { |
849 var dummy = document.createElement("body"); | 878 var dummy = document.createElement("body"); |
850 dummy.innerHTML = "<table><tr>" + html + "</tr></table>"; | 879 suspendScripts = true; |
851 runScripts(dummy); | 880 try { |
881 dummy.innerHTML = "<table><tr>" + html + "</tr></table>"; | |
882 } catch (e) { | |
883 suspendScripts = false; | |
884 throw e; | |
885 } | |
886 | |
852 var table = x.parentNode; | 887 var table = x.parentNode; |
853 | 888 |
854 if (table) { | 889 if (table) { |
855 var arr = dummy.getElementsByTagName("tr"); | 890 var arr = dummy.getElementsByTagName("tr"); |
856 firstChild = null; | 891 firstChild = null; |
864 firstChild = document.createElement("script"); | 899 firstChild = document.createElement("script"); |
865 table.insertBefore(firstChild, x); | 900 table.insertBefore(firstChild, x); |
866 for (var node = tr.firstChild; node; node = next) { | 901 for (var node = tr.firstChild; node; node = next) { |
867 next = node.nextSibling; | 902 next = node.nextSibling; |
868 table.insertBefore(node, x); | 903 table.insertBefore(node, x); |
904 suspendScripts = false; | |
905 runScripts(node); | |
906 suspendScripts = true; | |
869 } | 907 } |
870 } | 908 }; |
909 | |
910 suspendScripts = false; | |
871 } else { | 911 } else { |
872 firstChild = document.createElement("span"); | 912 firstChild = document.createElement("span"); |
873 firstChild.innerHTML = html; | 913 |
914 suspendScripts = true; | |
915 try { | |
916 firstChild.innerHTML = html; | |
917 if (x.parentNode) | |
918 x.parentNode.insertBefore(firstChild, x); | |
919 } catch (e) { | |
920 suspendScripts = false; | |
921 throw e; | |
922 } | |
923 suspendScripts = false; | |
874 runScripts(firstChild); | 924 runScripts(firstChild); |
875 if (x.parentNode) | |
876 x.parentNode.insertBefore(firstChild, x); | |
877 } | 925 } |
878 }; | 926 }; |
879 | 927 |
880 addNode(x); | 928 addNode(x); |
881 populate(x); | 929 populate(x); |
907 } | 955 } |
908 | 956 |
909 var cls = {v : null}; | 957 var cls = {v : null}; |
910 var html = flatten(cls, html); | 958 var html = flatten(cls, html); |
911 x.closures = cls.v; | 959 x.closures = cls.v; |
960 suspendScripts = true; | |
912 node.innerHTML = html; | 961 node.innerHTML = html; |
962 suspendScripts = false; | |
913 runScripts(node); | 963 runScripts(node); |
914 } | 964 } |
915 | 965 |
916 var maySuspend = true; | 966 var maySuspend = true; |
917 | 967 |
918 function active(s) { | 968 function active(s) { |
969 if (suspendScripts) | |
970 return; | |
971 | |
919 var span = document.createElement("span"); | 972 var span = document.createElement("span"); |
920 addNode(span); | 973 addNode(span); |
921 var ms = maySuspend; | 974 var ms = maySuspend; |
922 maySuspend = false; | 975 maySuspend = false; |
923 try { | 976 try { |
942 | 995 |
943 return x; | 996 return x; |
944 } | 997 } |
945 | 998 |
946 function inp(s, name) { | 999 function inp(s, name) { |
1000 if (suspendScripts) | |
1001 return; | |
1002 | |
947 var x = input(document.createElement("input"), s, | 1003 var x = input(document.createElement("input"), s, |
948 function(x) { return function(v) { if (x.value != v) x.value = v; }; }, null, name); | 1004 function(x) { return function(v) { if (x.value != v) x.value = v; }; }, null, name); |
949 x.value = s.data; | 1005 x.value = s.data; |
950 x.onkeyup = x.oninput = x.onchange = x.onpropertychange = function() { sv(s, x.value) }; | 1006 x.onkeyup = x.oninput = x.onchange = x.onpropertychange = function() { sv(s, x.value) }; |
951 | 1007 |
967 } | 1023 } |
968 } | 1024 } |
969 } | 1025 } |
970 | 1026 |
971 function sel(s, content) { | 1027 function sel(s, content) { |
1028 if (suspendScripts) | |
1029 return; | |
1030 | |
972 var dummy = document.createElement("span"); | 1031 var dummy = document.createElement("span"); |
973 dummy.innerHTML = "<select>" + content + "</select>"; | 1032 dummy.innerHTML = "<select>" + content + "</select>"; |
974 var x = input(dummy.firstChild, s, function(x) { return function(v) { if (selectValue(x) != v) setSelectValue(x, v); }; }); | 1033 var x = input(dummy.firstChild, s, function(x) { return function(v) { if (selectValue(x) != v) setSelectValue(x, v); }; }); |
975 | 1034 |
976 for (var i = 0; i < x.options.length; ++i) { | 1035 for (var i = 0; i < x.options.length; ++i) { |
987 | 1046 |
988 return x; | 1047 return x; |
989 } | 1048 } |
990 | 1049 |
991 function chk(s) { | 1050 function chk(s) { |
1051 if (suspendScripts) | |
1052 return; | |
1053 | |
992 var x = input(document.createElement("input"), s, | 1054 var x = input(document.createElement("input"), s, |
993 function(x) { return function(v) { if (x.checked != v) x.checked = v; }; }, "checkbox"); | 1055 function(x) { return function(v) { if (x.checked != v) x.checked = v; }; }, "checkbox"); |
994 x.defaultChecked = x.checked = s.data; | 1056 x.defaultChecked = x.checked = s.data; |
995 x.onclick = x.onkeyup = x.oninput = x.onchange = x.onpropertychange = function() { sv(s, x.checked) }; | 1057 x.onclick = x.onkeyup = x.oninput = x.onchange = x.onpropertychange = function() { sv(s, x.checked) }; |
996 | 1058 |
997 return x; | 1059 return x; |
998 } | 1060 } |
999 | 1061 |
1000 function tbx(s) { | 1062 function tbx(s) { |
1063 if (suspendScripts) | |
1064 return; | |
1065 | |
1001 var x = input(document.createElement("textarea"), s, | 1066 var x = input(document.createElement("textarea"), s, |
1002 function(x) { return function(v) { if (x.value != v) x.value = v; }; }); | 1067 function(x) { return function(v) { if (x.value != v) x.value = v; }; }); |
1003 x.innerHTML = s.data; | 1068 x.innerHTML = s.data; |
1004 x.onkeyup = x.oninput = x.onchange = x.onpropertychange = function() { sv(s, x.value) }; | 1069 x.onkeyup = x.oninput = x.onchange = x.onpropertychange = function() { sv(s, x.value) }; |
1005 | 1070 |
1006 return x; | 1071 return x; |
1007 } | 1072 } |
1008 | 1073 |
1009 function dynClass(html, s_class, s_style) { | 1074 function dynClass(html, s_class, s_style) { |
1075 if (suspendScripts) | |
1076 return; | |
1077 | |
1010 var htmlCls = {v : null}; | 1078 var htmlCls = {v : null}; |
1011 html = flatten(htmlCls, html); | 1079 html = flatten(htmlCls, html); |
1012 htmlCls = htmlCls.v; | 1080 htmlCls = htmlCls.v; |
1013 | 1081 |
1014 var dummy = document.createElement("body"); | 1082 var dummy = document.createElement("body"); |
1083 suspendScripts = true; | |
1015 dummy.innerHTML = html; | 1084 dummy.innerHTML = html; |
1085 suspendScripts = false; | |
1016 var html = dummy.firstChild; | 1086 var html = dummy.firstChild; |
1017 dummy.removeChild(html); | 1087 dummy.removeChild(html); |
1018 addNode(html); | 1088 addNode(html); |
1019 runScripts(html); | 1089 runScripts(html); |
1020 | 1090 |
1861 function fresh() { | 1931 function fresh() { |
1862 return "uw" + (--nextId); | 1932 return "uw" + (--nextId); |
1863 } | 1933 } |
1864 | 1934 |
1865 function giveFocus(id) { | 1935 function giveFocus(id) { |
1866 window.setTimeout(function() { | 1936 var node = document.getElementById(id); |
1867 var node = document.getElementById(id); | 1937 |
1868 | 1938 if (node) |
1869 if (node) | 1939 node.focus(); |
1870 node.focus(); | 1940 else |
1871 else | 1941 er("Tried to give focus to ID not used in document: " + id); |
1872 er("Tried to give focus to ID not used in document: " + id); | |
1873 }, 0); | |
1874 } | 1942 } |
1875 | 1943 |
1876 | 1944 |
1877 // App-specific code | 1945 // App-specific code |