|
214 | 214 | "use strict"; |
215 | 215 |
|
216 | 216 | var document = window.document; |
217 | | - var gcs = window.getComputedStyle; |
| 217 | + var gcs = function (x) { return window.getComputedStyle(x) }; |
218 | 218 | var isUndefined = function (x) { return typeof(x) == 'undefined'; }; |
219 | 219 |
|
220 | | - var noBrowser = isUndefined(document) || isUndefined(gcs); |
| 220 | + var noBrowser = isUndefined(document); |
221 | 221 |
|
222 | 222 | var toSet = function (s) { |
223 | 223 | for (var d = {}, i = (s = s.split(',')).length; i--;) d[s[i]] = 1; |
|
236 | 236 | var stringTrimRe = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; |
237 | 237 | var splitWordsRe = /(?:(?:^|[A-Z])[a-z]+|[0-9]+|[A-Za-z]+)/g; |
238 | 238 |
|
239 | | - var hashPopRe = /(?:(^\/)|\/)[^\/]+[\/]*$/; // $1 |
240 | | - var hashResolveRe = /^#\/?|(\/)(?:\.?\/)+|(?:(?!\.\.?)[^\/])+\/\.\.(?:\/|$)|([^\^])\/+$/; |
241 | | - var hashCompsRe = /(?:(^|\/)(:?)([^\/]+))/g; |
242 | 239 | var locationPathPopRe = /((^|\/)[^\/]*)$/; |
243 | 240 | var htmlTagRe = /^[\w]+$/; |
244 | 241 |
|
|
854 | 851 | svgPath[c] = svgPathAppender(c); |
855 | 852 |
|
856 | 853 | HTML.SVG.Path = svgPath; |
| 854 | + |
| 855 | + var onceDones = {}; |
| 856 | + var once = function (k, t, f) { |
| 857 | + if (onceDones[k]) { |
| 858 | + if (isFunction(f)) f(); |
| 859 | + return false; |
| 860 | + } else { |
| 861 | + onceDones[k] = 1; |
| 862 | + if (isFunction(t)) t(); |
| 863 | + } |
| 864 | + return true; |
| 865 | + }; |
| 866 | + once.clear = function (k) { |
| 867 | + delete onceDones[k]; |
| 868 | + return once; |
| 869 | + }; |
| 870 | + HTML.once = once; |
| 871 | + |
| 872 | + var hashPopRe = /(?:(^\/)|\/)[^\/]+[\/]*$/; // $1 |
| 873 | + var hashResolveRe = /^#?\/?|(\/)(?:\.?\/)+|(?:(?!\.\.?)[^\/])+\/\.\.(?:\/|$)|([^\^])\/+$/; |
| 874 | + var hashCompsRe = /(?:(^|\/)(:?)([^\/]+))/g; |
857 | 875 |
|
858 | | - var routes = {}, savedRoutes = {}, routesInited = 0, refreshable = 0; |
| 876 | + var routes = {}, savedRoutes = {}, routesInited = 0, refreshable = 0, visited = []; |
859 | 877 |
|
860 | 878 | var hashResolve = function (h) { |
861 | 879 | for (var p, t = 1; t; ) { |
|
865 | 883 | } |
866 | 884 | return h; |
867 | 885 | }; |
| 886 | + var setVisited = function (p) { |
| 887 | + if (visited.length < 1) { |
| 888 | + setTimeout(function () { |
| 889 | + visited = []; |
| 890 | + }, 60); |
| 891 | + } |
| 892 | + visited.push(p); |
| 893 | + } |
| 894 | + |
868 | 895 | //HTML.hashResolve = hashResolve; |
869 | 896 | var execRoute = function (h, s) { |
870 | | - var p = '', j, c, m, a = hashResolve(h); |
| 897 | + var p = '', j, c, m, a = hashResolve(h), t = h.length; |
871 | 898 | while (m = hashCompsRe.exec(a)) { |
872 | 899 | p += m[1]; |
873 | 900 | c = m[3]; |
|
876 | 903 | if (!s) savedRoutes[p] = c; |
877 | 904 | p += c; |
878 | 905 | } |
879 | | - for (j = p; j; j = j.replace(hashPopRe, '$1')) { |
| 906 | + for (j = p; j && t > 0; j = j.replace(hashPopRe, '$1')) { |
880 | 907 | if (routes[j]) { |
881 | 908 | p = j; |
882 | 909 | j = ''; |
883 | 910 | } |
| 911 | + --t; |
| 912 | + } |
| 913 | + if (!s && isFunction(c = routes[p])) { |
| 914 | + if (visited.indexOf(p) < 0) { |
| 915 | + setVisited(p); |
| 916 | + c(); |
| 917 | + } else { |
| 918 | + var v = h.replace('/:', '/'); |
| 919 | + if (v != h && visited.indexOf(v) < 0) { |
| 920 | + execRoute(v); |
| 921 | + } |
| 922 | + } |
884 | 923 | } |
885 | | - if (!s && isFunction(c = routes[p])) c(); |
886 | 924 | return p; |
887 | 925 | }; |
888 | 926 |
|
|
938 | 976 | // HTML.route('a', fn).route('b', fn) |
939 | 977 | return HTML; |
940 | 978 | } |
941 | | - // If no args are provided, |
942 | | - // return the window.location.hash splitted. |
943 | 979 | return routes[execRoute(hashResolve(r), 1)]; |
944 | 980 | }; |
945 | 981 |
|
|
0 commit comments