OLD | NEW |
1 #import ("dart:html"); | 1 #import ("dart:html"); |
2 #import ("dart:json"); | 2 #import ("dart:json"); |
3 | 3 |
4 // Workaround for HTML lib missing feature. | 4 // Workaround for HTML lib missing feature. |
5 Range newRange() { | 5 Range newRange() { |
6 return document.createRange(); | 6 return document.createRange(); |
7 } | 7 } |
8 | 8 |
9 // Temporary range object to optimize performance computing client rects | 9 // Temporary range object to optimize performance computing client rects |
10 // from text nodes. | 10 // from text nodes. |
(...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 continue; | 827 continue; |
828 } | 828 } |
829 | 829 |
830 // After this point we have higher risk tests that attempt to perform | 830 // After this point we have higher risk tests that attempt to perform |
831 // rudimentary page segmentation. This approach is much more error-prone | 831 // rudimentary page segmentation. This approach is much more error-prone |
832 // than using tables because the HTML is far less clearly structured. | 832 // than using tables because the HTML is far less clearly structured. |
833 | 833 |
834 final allText = getAllTextNodes(match); | 834 final allText = getAllTextNodes(match); |
835 | 835 |
836 final pmap = new Map<String, Element>(); | 836 final pmap = new Map<String, Element>(); |
837 for (final prop in expectedProps.getKeys()) { | 837 for (final prop in expectedProps.keys) { |
838 if (alreadyMatchedProperties.contains(prop)) { | 838 if (alreadyMatchedProperties.contains(prop)) { |
839 continue; | 839 continue; |
840 } | 840 } |
841 final e = findBest(match, allText, prop, propType); | 841 final e = findBest(match, allText, prop, propType); |
842 if (e != null && !inTable(e)) { | 842 if (e != null && !inTable(e)) { |
843 pmap[prop] = e; | 843 pmap[prop] = e; |
844 } | 844 } |
845 } | 845 } |
846 | 846 |
847 for (final prop in pmap.getKeys()) { | 847 for (final prop in pmap.keys) { |
848 pmap[prop].classes.add(DART_REMOVED); | 848 pmap[prop].classes.add(DART_REMOVED); |
849 } | 849 } |
850 | 850 |
851 // The problem is the MDN docs do place documentation for each method in a | 851 // The problem is the MDN docs do place documentation for each method in a |
852 // nice self contained subtree. Instead you will see something like: | 852 // nice self contained subtree. Instead you will see something like: |
853 | 853 |
854 // <h3>drawImage</h3> | 854 // <h3>drawImage</h3> |
855 // <p>Draw image is an awesome method</p> | 855 // <p>Draw image is an awesome method</p> |
856 // some more info on drawImage here | 856 // some more info on drawImage here |
857 // <h3>mozDrawWindow</h3> | 857 // <h3>mozDrawWindow</h3> |
(...skipping 10 matching lines...) Expand all Loading... |
868 // careful the definition for the drawImage method will contain the | 868 // careful the definition for the drawImage method will contain the |
869 // definition for the mozDrawWindow method as well which would result in | 869 // definition for the mozDrawWindow method as well which would result in |
870 // broken docs. We solve this problem by finding all content with similar | 870 // broken docs. We solve this problem by finding all content with similar |
871 // visual structure to the already found method definitions. It turns out | 871 // visual structure to the already found method definitions. It turns out |
872 // that using the visual position of each element on the page is much | 872 // that using the visual position of each element on the page is much |
873 // more reliable than using the DOM structure | 873 // more reliable than using the DOM structure |
874 // (e.g. section_root > div > h3) for the MDN docs because MDN authors | 874 // (e.g. section_root > div > h3) for the MDN docs because MDN authors |
875 // carefully check that the documentation for each method comment is | 875 // carefully check that the documentation for each method comment is |
876 // visually consistent but take less care to check that each | 876 // visually consistent but take less care to check that each |
877 // method comment has identical markup structure. | 877 // method comment has identical markup structure. |
878 for (String prop in pmap.getKeys()) { | 878 for (String prop in pmap.keys) { |
879 Element e = pmap[prop]; | 879 Element e = pmap[prop]; |
880 ClientRect r = getClientRect(e); | 880 ClientRect r = getClientRect(e); |
881 // TODO(jacobr): a lot of these queries are identical and this code | 881 // TODO(jacobr): a lot of these queries are identical and this code |
882 // could easily be optimized. | 882 // could easily be optimized. |
883 for (final cand in match.queryAll(e.tagName)) { | 883 for (final cand in match.queryAll(e.tagName)) { |
884 // TODO(jacobr): use a negative selector instead. | 884 // TODO(jacobr): use a negative selector instead. |
885 if (!cand.classes.contains(DART_REMOVED) && !inTable(cand)) { | 885 if (!cand.classes.contains(DART_REMOVED) && !inTable(cand)) { |
886 final candRect = getClientRect(cand); | 886 final candRect = getClientRect(cand); |
887 // Only consider matches that have similar heights and identical left | 887 // Only consider matches that have similar heights and identical left |
888 // coordinates. | 888 // coordinates. |
889 if (candRect.left == r.left && | 889 if (candRect.left == r.left && |
890 (candRect.height - r.height).abs() < 5) { | 890 (candRect.height - r.height).abs() < 5) { |
891 String propName = fullNameCleanup(cand.text); | 891 String propName = fullNameCleanup(cand.text); |
892 if (isFirstCharLowerCase(propName) && !pmap.containsKey(propName) | 892 if (isFirstCharLowerCase(propName) && !pmap.containsKey(propName) |
893 && !alreadyMatchedProperties.contains(propName)) { | 893 && !alreadyMatchedProperties.contains(propName)) { |
894 pmap[propName] = cand; | 894 pmap[propName] = cand; |
895 } | 895 } |
896 } | 896 } |
897 } | 897 } |
898 } | 898 } |
899 } | 899 } |
900 | 900 |
901 // We mark these elements in batch to reduce the number of layouts | 901 // We mark these elements in batch to reduce the number of layouts |
902 // triggered. TODO(jacobr): use new batch based async measurement to make | 902 // triggered. TODO(jacobr): use new batch based async measurement to make |
903 // this code flow simpler. | 903 // this code flow simpler. |
904 for (String prop in pmap.getKeys()) { | 904 for (String prop in pmap.keys) { |
905 Element e = pmap[prop]; | 905 Element e = pmap[prop]; |
906 e.classes.add(DART_REMOVED); | 906 e.classes.add(DART_REMOVED); |
907 } | 907 } |
908 | 908 |
909 // Find likely "subsections" of the main section and mark them with | 909 // Find likely "subsections" of the main section and mark them with |
910 // DART_REMOVED so we don't include them in member descriptions... which | 910 // DART_REMOVED so we don't include them in member descriptions... which |
911 // would suck. | 911 // would suck. |
912 for (Element e in match.queryAll("[id]")) { | 912 for (Element e in match.queryAll("[id]")) { |
913 if (e.id.contains(matchElement.id)) { | 913 if (e.id.contains(matchElement.id)) { |
914 e.classes.add(DART_REMOVED); | 914 e.classes.add(DART_REMOVED); |
915 } | 915 } |
916 } | 916 } |
917 | 917 |
918 for (String prop in pmap.getKeys()) { | 918 for (String prop in pmap.keys) { |
919 Element elem = pmap[prop]; | 919 Element elem = pmap[prop]; |
920 bool obsolete = false; | 920 bool obsolete = false; |
921 final parse = filteredHtml( | 921 final parse = filteredHtml( |
922 elem, match, prop, | 922 elem, match, prop, |
923 (Element e) { | 923 (Element e) { |
924 obsolete = isObsolete(e); | 924 obsolete = isObsolete(e); |
925 }); | 925 }); |
926 Map entry = { | 926 Map entry = { |
927 "url" : parse.url, | 927 "url" : parse.url, |
928 "name" : prop, | 928 "name" : prop, |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1024 * values performing some simple normalization and only adding the entry to | 1024 * values performing some simple normalization and only adding the entry to |
1025 * [members] if it has a valid name. | 1025 * [members] if it has a valid name. |
1026 */ | 1026 */ |
1027 void cleanupEntry(List members, Map entry) { | 1027 void cleanupEntry(List members, Map entry) { |
1028 if (entry.containsKey('help')) { | 1028 if (entry.containsKey('help')) { |
1029 entry['help'] = trimHtml(entry['help']); | 1029 entry['help'] = trimHtml(entry['help']); |
1030 } | 1030 } |
1031 String name = fullNameCleanup(entry['name']); | 1031 String name = fullNameCleanup(entry['name']); |
1032 entry['name'] = name; | 1032 entry['name'] = name; |
1033 if (maybeName(name)) { | 1033 if (maybeName(name)) { |
1034 for (String key in entry.getKeys()) { | 1034 for (String key in entry.keys) { |
1035 var value = entry[key]; | 1035 var value = entry[key]; |
1036 if (value == null) { | 1036 if (value == null) { |
1037 entry.remove(key); | 1037 entry.remove(key); |
1038 continue; | 1038 continue; |
1039 } | 1039 } |
1040 if (value is String) { | 1040 if (value is String) { |
1041 entry[key] = JSONFIXUPHACK(value); | 1041 entry[key] = JSONFIXUPHACK(value); |
1042 } | 1042 } |
1043 } | 1043 } |
1044 members.add(entry); | 1044 members.add(entry); |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 } | 1305 } |
1306 | 1306 |
1307 void documentLoaded(event) { | 1307 void documentLoaded(event) { |
1308 // Load the database of expected methods and properties with an HttpRequest. | 1308 // Load the database of expected methods and properties with an HttpRequest. |
1309 new HttpRequest.get('${window.location}.json', (req) { | 1309 new HttpRequest.get('${window.location}.json', (req) { |
1310 data = JSON.parse(req.responseText); | 1310 data = JSON.parse(req.responseText); |
1311 dbEntry = {'members': [], 'srcUrl': pageUrl}; | 1311 dbEntry = {'members': [], 'srcUrl': pageUrl}; |
1312 run(); | 1312 run(); |
1313 }); | 1313 }); |
1314 } | 1314 } |
OLD | NEW |