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