├── .gitignore ├── CHANGES ├── README ├── conf └── nginx.conf ├── htdocs ├── CHANGES ├── blank.html ├── css │ ├── jquery-ui │ │ ├── Aristo │ │ │ ├── aristo.css │ │ │ ├── images │ │ │ │ ├── aristo.png │ │ │ │ ├── bg_fallback.png │ │ │ │ ├── icon_sprite.png │ │ │ │ ├── progress_bar.gif │ │ │ │ ├── slider_handles.png │ │ │ │ ├── ui-icons_222222_256x240.png │ │ │ │ └── ui-icons_454545_256x240.png │ │ │ └── jquery-ui-1.8.7.custom.css │ │ ├── images │ │ │ ├── ui-bg_flat_10%_eceadf_40x100.png │ │ │ ├── ui-bg_flat_15_eceadf_40x100.png │ │ │ ├── ui-bg_flat_15_f7f3de_40x100.png │ │ │ ├── ui-bg_flat_15_ffffff_40x100.png │ │ │ ├── ui-bg_flat_20_6e4f1c_40x100.png │ │ │ ├── ui-bg_flat_40_000000_40x100.png │ │ │ ├── ui-bg_flat_65_654b24_40x100.png │ │ │ ├── ui-bg_flat_68_b83400_40x100.png │ │ │ ├── ui-bg_glass_50_f8f7f6_1x400.png │ │ │ ├── ui-icons_222222_256x240.png │ │ │ ├── ui-icons_3572ac_256x240.png │ │ │ ├── ui-icons_8c291d_256x240.png │ │ │ ├── ui-icons_b83400_256x240.png │ │ │ ├── ui-icons_fbdb93_256x240.png │ │ │ └── ui-icons_ffffff_256x240.png │ │ ├── jquery-ui-1.8.6.custom.css │ │ ├── jquery-ui-1.8.7.custom.css │ │ └── jquery-ui.custom.css │ ├── pod.css │ └── screen.css ├── images │ ├── background_black.png │ ├── background_black_02.png │ ├── background_black_04.png │ ├── background_black_05.png │ ├── background_black_07.png │ ├── background_black_08.png │ ├── background_black_10.png │ ├── background_black_12.png │ ├── background_black_15.png │ ├── background_black_20.png │ ├── beta.png │ ├── buttonbg.png │ ├── favicon.ico │ ├── icon_color_arrow.gif │ ├── loader.gif │ ├── loader_wide.gif │ ├── menuhoverbg.png │ ├── metacpan_logo.png │ └── metacpan_logo_flat.png ├── index.html ├── js │ ├── ICanHaz.min.js │ ├── backbone-min.js │ ├── controllers.js │ ├── encoder.js │ ├── jquery-ui-1.8.6.custom.min.js │ ├── jquery.ba-bbq.js │ ├── jquery.ba-bbq.min.js │ ├── jquery.ba-hashchange.min.js │ ├── jquery.cookie.js │ ├── jquery.cookie.min.js │ ├── jquery.dataTables.js │ ├── jquery.dataTables.min.js │ ├── jquery.text-overflow.js │ ├── jquery.text-overflow.min.js │ ├── jquery.themeswitchertool.js │ ├── json2.js │ ├── json2.min.js │ ├── main.js │ ├── models.js │ ├── mustache.js │ ├── mustache.min.js │ ├── scripts.js │ ├── templates.js │ ├── underscore-min.js │ └── views.js ├── robots.txt └── sitemap.xml ├── misc_resources ├── background_black.png ├── favicon.ico ├── metacpan_icon.ai ├── metacpan_icon.png ├── metacpan_logo.ai ├── metacpan_logo.png ├── metacpan_logo.psd └── metacpan_logo_square.png ├── search-metacpan-org.komodoproject └── search-metacpan-org.kpf /.gitignore: -------------------------------------------------------------------------------- 1 | # folders to ignore 2 | logs/ 3 | 4 | # individual files to ignore 5 | 6 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | CHANGE LOG 2 | 3 | 2011-07-28 4 | 5 | * moved search.metacpan.org to js.metacpan.org 6 | 7 | 2011-06-29 8 | 9 | * fixed display issue on author details view whene the author had multiple email addresses 10 | * fixed display issue of gravatar on pod details view 11 | 12 | 2011-06-27 13 | 14 | * Removed erroneous 'l' in the podView template 15 | * Changed the Google Groups link to https://groups.google.com/forum/#!forum/cpan-api due to issue with Google Grooups changing their URL scheme. Fixes issues #31. 16 | 17 | 2011-06-04 18 | 19 | * ported to use the new MetaCPAN API 20 | 21 | 2011-03-18 22 | 23 | * combined the module name and description columns into one column on all search results tables 24 | 25 | 2011-02-14 26 | 27 | * fixed issue with description column causing the html to break when the module/dist description contained greater than or less than signs 28 | * fixed issue where urls that that had escaped characters would not work except in Firefox 29 | * now using json instead of jsonp ajax calls -- this fixes an issue with the loader image never disappearing when searching an invalid author 30 | * the tweet button now has via @metacpan as the default text instead of via @ioncache 31 | 32 | 2011-01-09 33 | 34 | * added a change log to the homepage 35 | * added links to CPAN Testers and Dependencies to the dist details page 36 | * added dist description to the dist details page 37 | 38 | 2011-01-07 39 | 40 | * added module and dist abstracts to all result tables 41 | 42 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Proof of concept site for using api.metacpan.org 2 | 3 | This site is now available at http://js.metacpan.org 4 | -------------------------------------------------------------------------------- /conf/nginx.conf: -------------------------------------------------------------------------------- 1 | # sample nginx server for search.metacpan.org 2 | 3 | server { 4 | 5 | server_name js.metacpan.org; 6 | 7 | access_log /home/metacpan/search.metacpan.org/logs/access.log; 8 | error_log /home/metacpan/search.metacpan.org/logs/error.log; 9 | 10 | root /home/metacpan/search.metacpan.org/htdocs; 11 | 12 | location / { 13 | index index.html; 14 | } 15 | 16 | location /source { 17 | proxy_pass http://api.metacpan.org/v0/source; 18 | } 19 | 20 | location /api { 21 | rewrite /api/(.*) /$1 break; 22 | proxy_pass http://api.metacpan.org/v0; 23 | } 24 | 25 | #location /images { 26 | # access_log off; 27 | # autoindex on; 28 | #} 29 | 30 | #expires modified +7d; 31 | 32 | gzip on; 33 | gzip_proxied any; 34 | gzip_http_version 1.0; 35 | gzip_vary on; 36 | gzip_buffers 16 8k; 37 | gzip_types text/plain text/css text/javascript image/x-icon image/bmp application/xml; 38 | gzip_disable "MSIE [1-6]\."; 39 | 40 | #error_page 404 /404.html; 41 | 42 | } 43 | 44 | server { 45 | 46 | server_name search.metacpan.org; 47 | 48 | location / { 49 | rewrite /(.*) https://metacpan.org/$1 break; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /htdocs/CHANGES: -------------------------------------------------------------------------------- 1 | ../CHANGES -------------------------------------------------------------------------------- /htdocs/blank.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/blank.html -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/Aristo/images/aristo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/Aristo/images/aristo.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/Aristo/images/bg_fallback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/Aristo/images/bg_fallback.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/Aristo/images/icon_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/Aristo/images/icon_sprite.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/Aristo/images/progress_bar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/Aristo/images/progress_bar.gif -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/Aristo/images/slider_handles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/Aristo/images/slider_handles.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/Aristo/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/Aristo/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/Aristo/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/Aristo/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-bg_flat_10%_eceadf_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-bg_flat_10%_eceadf_40x100.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-bg_flat_15_eceadf_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-bg_flat_15_eceadf_40x100.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-bg_flat_15_f7f3de_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-bg_flat_15_f7f3de_40x100.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-bg_flat_15_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-bg_flat_15_ffffff_40x100.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-bg_flat_20_6e4f1c_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-bg_flat_20_6e4f1c_40x100.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-bg_flat_40_000000_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-bg_flat_40_000000_40x100.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-bg_flat_65_654b24_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-bg_flat_65_654b24_40x100.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-bg_flat_68_b83400_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-bg_flat_68_b83400_40x100.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-bg_glass_50_f8f7f6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-bg_glass_50_f8f7f6_1x400.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-icons_3572ac_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-icons_3572ac_256x240.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-icons_8c291d_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-icons_8c291d_256x240.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-icons_b83400_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-icons_b83400_256x240.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-icons_fbdb93_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-icons_fbdb93_256x240.png -------------------------------------------------------------------------------- /htdocs/css/jquery-ui/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/css/jquery-ui/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /htdocs/css/pod.css: -------------------------------------------------------------------------------- 1 | .pod { 2 | width: 100%; 3 | } 4 | .pod pre { 5 | width: 100%; 6 | background: #FFFFFF; 7 | border: 1px solid #681818; 8 | color: black; 9 | padding: 1em; 10 | white-space: pre-wrap; /* css-3 */ 11 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 12 | white-space: -pre-wrap; /* Opera 4-6 */ 13 | white-space: -o-pre-wrap; /* Opera 7 */ 14 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 15 | } 16 | 17 | .pod code { 18 | white-space: pre-wrap; /* css-3 */ 19 | white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ 20 | white-space: -pre-wrap; /* Opera 4-6 */ 21 | white-space: -o-pre-wrap; /* Opera 7 */ 22 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 23 | } 24 | 25 | .pod a { 26 | color: #681818; 27 | text-decoration: underline; 28 | font-size: 1em; 29 | } 30 | 31 | .pod a:visited { 32 | color: #453821; 33 | } 34 | 35 | .pod a:hover { 36 | text-decoration: none; 37 | } 38 | 39 | .pod h1 { 40 | background: transparent; 41 | color: #681818; 42 | font-size: 1.7em; 43 | } 44 | 45 | .pod h1 a { text-decoration: none; } 46 | .pod h2 a { text-decoration: none; } 47 | .pod h3 a { text-decoration: none; } 48 | .pod h4 a { text-decoration: none; } 49 | 50 | .pod h2 { 51 | background: transparent; 52 | color: #681818; 53 | font-size: 1.5em; 54 | } 55 | 56 | .pod h3 { 57 | background: transparent; 58 | color: #681818; 59 | font-size: 1.3em; 60 | font-style: italic; 61 | } 62 | 63 | .pod h4 { 64 | background: transparent; 65 | color: #681818; 66 | font-size: 1.1em; 67 | font-weight: normal; 68 | } 69 | 70 | .pod img { 71 | border: none; 72 | vertical-align: top; 73 | } 74 | 75 | .pod #index { 76 | padding: 0px; 77 | } 78 | 79 | .pod #index li { 80 | list-style-type: none; 81 | margin: .3em 0; 82 | } 83 | 84 | .pod #index ul { 85 | padding-left: 1.5em; 86 | } 87 | 88 | .pod #index a:visited { 89 | color: #681818; 90 | } 91 | 92 | #module_details_header { 93 | float: left; 94 | color: #681818; 95 | border-bottom: 1px solid #681818; 96 | padding-bottom: 10px; 97 | } 98 | 99 | #module_details_header .module_name { 100 | float: left; 101 | width: 600px; 102 | font-size: 1.8em; 103 | color: #681818; 104 | } 105 | 106 | #module_details_header .fb_box { 107 | float: left; 108 | width: 300px; 109 | text-align: right; 110 | } 111 | 112 | #module_details_header .module_info { 113 | float: left; 114 | width: 600px; 115 | font-size: 1em; 116 | color: #654b24; 117 | } 118 | 119 | #module_details_header .author_info { 120 | position: relative; 121 | float: left; 122 | width: 300px; 123 | font-size: 1.2em; 124 | color: #654b24; 125 | text-align: right; 126 | } 127 | 128 | #module_details_header .gravatar { 129 | position: absolute; 130 | bottom: -105px; 131 | right: 0px; 132 | border: 0; 133 | } 134 | 135 | #module_details_header .separator { 136 | float: left; 137 | width: 100%; 138 | height: 4px; 139 | margin: 5px 0; 140 | background-color: #6e4f1c; 141 | } -------------------------------------------------------------------------------- /htdocs/css/screen.css: -------------------------------------------------------------------------------- 1 | .palette { 2 | color: #1f1f1f; 3 | color: #eceadf; 4 | color: #453821; 5 | color: #654b24; 6 | color: #140f06; 7 | color: #3a3427; 8 | color: #6e4f1c; 9 | color: #b83400; 10 | color: #fbdb93; 11 | color: #681818; 12 | } 13 | 14 | html { 15 | overflow-y: scroll; 16 | } 17 | 18 | html, body { 19 | height: 100%; 20 | } 21 | 22 | body { 23 | font-size: 12px; 24 | font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; 25 | padding-top: 10px; 26 | } 27 | 28 | a { 29 | color: #b83400; 30 | font-size: 1.1em; 31 | font-weight: bold; 32 | text-decoration: none; 33 | } 34 | 35 | a:hover { 36 | text-decoration: underline; 37 | } 38 | 39 | #main_container { 40 | position: relative; 41 | width: 900px; 42 | min-height: 100%; 43 | height: auto !important; 44 | height: 100%; 45 | margin: 0 auto; 46 | } 47 | 48 | #footer { 49 | position: fixed; 50 | bottom: 0; 51 | width: 100%; 52 | height: 60px; 53 | text-align: center; 54 | background-color: #FFFFFF; 55 | } 56 | 57 | .spacer { 58 | width: 900px; 59 | height: 80px; 60 | margin: 0 auto; 61 | } 62 | 63 | #search_box { 64 | text-align: center; 65 | margin-bottom: 10px; 66 | } 67 | 68 | #search_input { 69 | width: 450px; 70 | height: 20px; 71 | line-height: 20px; 72 | font-size: 1.2em; 73 | color: #140f06; 74 | } 75 | 76 | .results_table { 77 | margin: 0 auto; 78 | clear: both; 79 | width: 100%; 80 | } 81 | 82 | .results_table a { 83 | color: #b83400; 84 | font-size: 1em; 85 | text-decoration: none; 86 | } 87 | 88 | .results_table th { 89 | text-align: left; 90 | font-weight: bold; 91 | cursor: pointer; 92 | } 93 | 94 | .results_table tr { 95 | cursor: pointer; 96 | } 97 | 98 | .results_table td, .results_table th { 99 | height: 20px; 100 | padding: 5px; 101 | line-height: 20px; 102 | white-space: nowrap; 103 | overflow: hidden; 104 | } 105 | 106 | .results_table td.center { 107 | text-align: center; 108 | } 109 | 110 | .cell_contents { 111 | white-space: nowrap; 112 | overflow: hidden; 113 | text-overflow: ellipsis; 114 | } 115 | 116 | .name { 117 | font-size: 1.15em; 118 | font-weight: bold; 119 | } 120 | 121 | .description { 122 | font-style: italic; 123 | } 124 | 125 | .DataTables_sort_wrapper { 126 | position: relative; 127 | } 128 | 129 | .DataTables_sort_wrapper span { 130 | position: absolute; 131 | right: 0; 132 | top: 2px; 133 | } 134 | 135 | .css_left { 136 | float: left; 137 | } 138 | 139 | .css_right { 140 | float: right; 141 | } 142 | 143 | .row_overrides { 144 | font-weight: normal !important; 145 | background-image: none !important; 146 | } 147 | 148 | .odd_rows { 149 | background-color: #eceadf; 150 | } 151 | 152 | .sorting_1 { 153 | background-image: url('/images/background_black_12.png') !important; 154 | background-repeat: repeat; 155 | } 156 | 157 | .sorting_2 { 158 | background-image: url('/images/background_black_07.png') !important; 159 | background-repeat: repeat; 160 | } 161 | 162 | .sorting_3 { 163 | background-image: url('/images/background_black_02.png') !important; 164 | background-repeat: repeat; 165 | } 166 | 167 | .fg-toolbar { 168 | padding: 8px 10px; 169 | } 170 | 171 | .fg-button { 172 | min-width: 30px; 173 | } 174 | 175 | .dataTables_info { 176 | float: left; 177 | } 178 | 179 | .dataTables_paginate { 180 | float: right; 181 | text-align: right; 182 | } 183 | 184 | .dataTables_paginate .ui-button { 185 | padding: 0px 5px; 186 | margin: 0px !important; 187 | } 188 | 189 | .paging_full_numbers { 190 | width: 600px; 191 | height: 22px; 192 | line-height: 22px; 193 | } 194 | 195 | .dataTables_length { 196 | float: right; 197 | text-align: right; 198 | } 199 | 200 | .dataTables_filter { 201 | float: left; 202 | width: 50%; 203 | } 204 | 205 | .page_navigation { 206 | float: left; 207 | margin-bottom: 10px; 208 | } 209 | 210 | .page_navigation a { 211 | padding: 3px 5px; 212 | margin: 2px; 213 | color: #FFFFFF; 214 | text-decoration: none; 215 | float: left; 216 | font-size: 1em; 217 | font-weight: bold; 218 | background-color: #681818; 219 | } 220 | 221 | .active_page { 222 | background-color: #FFFFFF !important; 223 | color: #681818 !important; 224 | } 225 | 226 | .page_link { 227 | min-width: 20px; 228 | text-align: center; 229 | } 230 | 231 | .metacpanView { 232 | display: none; 233 | position: relative; 234 | } 235 | 236 | .loader { 237 | position: absolute; 238 | top: 20px; 239 | float: left; 240 | width: 100%; 241 | text-align: center; 242 | } 243 | 244 | .author_details_info { 245 | float: left; 246 | width: 860px; 247 | margin-bottom: 15px; 248 | padding: 20px; 249 | } 250 | 251 | .author_details_info .left { 252 | float: left; 253 | width: 760px; 254 | } 255 | 256 | .author_details_info .right { 257 | float: right; 258 | width: 80px; 259 | padding-left: 20px; 260 | } 261 | 262 | .author_details_info .contact_info { 263 | margin-bottom: 5px; 264 | } 265 | 266 | .author_details_info .contact_info_label { 267 | float: left; 268 | width: 110px; 269 | } 270 | 271 | .author_details_info .contact_info_value { 272 | float: left; 273 | } 274 | 275 | .source_header { 276 | width: 100%; 277 | height: 1.8em; 278 | font-size: 1.8em; 279 | color: #681818; 280 | border-bottom: 1px solid #681818; 281 | } 282 | 283 | .source_module_name { 284 | float: left; 285 | } 286 | 287 | .source_author_name { 288 | float: right; 289 | text-align: right; 290 | } 291 | 292 | #tweetbox { 293 | float: left; 294 | margin: 5px 0 0 20px; 295 | } 296 | 297 | .info { 298 | width: 600px; 299 | padding: 20px; 300 | margin: 25px auto; 301 | } -------------------------------------------------------------------------------- /htdocs/images/background_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/background_black.png -------------------------------------------------------------------------------- /htdocs/images/background_black_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/background_black_02.png -------------------------------------------------------------------------------- /htdocs/images/background_black_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/background_black_04.png -------------------------------------------------------------------------------- /htdocs/images/background_black_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/background_black_05.png -------------------------------------------------------------------------------- /htdocs/images/background_black_07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/background_black_07.png -------------------------------------------------------------------------------- /htdocs/images/background_black_08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/background_black_08.png -------------------------------------------------------------------------------- /htdocs/images/background_black_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/background_black_10.png -------------------------------------------------------------------------------- /htdocs/images/background_black_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/background_black_12.png -------------------------------------------------------------------------------- /htdocs/images/background_black_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/background_black_15.png -------------------------------------------------------------------------------- /htdocs/images/background_black_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/background_black_20.png -------------------------------------------------------------------------------- /htdocs/images/beta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/beta.png -------------------------------------------------------------------------------- /htdocs/images/buttonbg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/buttonbg.png -------------------------------------------------------------------------------- /htdocs/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/favicon.ico -------------------------------------------------------------------------------- /htdocs/images/icon_color_arrow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/icon_color_arrow.gif -------------------------------------------------------------------------------- /htdocs/images/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/loader.gif -------------------------------------------------------------------------------- /htdocs/images/loader_wide.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/loader_wide.gif -------------------------------------------------------------------------------- /htdocs/images/menuhoverbg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/menuhoverbg.png -------------------------------------------------------------------------------- /htdocs/images/metacpan_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/metacpan_logo.png -------------------------------------------------------------------------------- /htdocs/images/metacpan_logo_flat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metacpan/js-metacpan-org/b0c35a8699b07f63e7de70e77e1d9e7e5448fb5a/htdocs/images/metacpan_logo_flat.png -------------------------------------------------------------------------------- /htdocs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | js.metacpan.org 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | metacpan 25 | 26 | 27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 83 | 87 | 93 | 99 | 109 | 125 | 136 | 143 | 241 | 248 | 291 | 294 | 297 | 300 | 301 | 304 | 309 | 317 | 318 | 319 | 333 | 334 | 335 | 367 | 368 | 372 | 373 | 385 | 386 | 387 | 388 | -------------------------------------------------------------------------------- /htdocs/js/ICanHaz.min.js: -------------------------------------------------------------------------------- 1 | (function(i){var n=function(){var f=function(){};f.prototype={otag:"{{",ctag:"}}",pragmas:{},buffer:[],pragmas_implemented:{"IMPLICIT-ITERATOR":true},context:{},render:function(a,b,c,d){if(!d){this.context=b;this.buffer=[]}if(!this.includes("",a))if(d)return a;else{this.send(a);return}a=this.render_pragmas(a);a=this.render_section(a,b,c);if(d)return this.render_tags(a,b,c,d);this.render_tags(a,b,c,d)},send:function(a){a!=""&&this.buffer.push(a)},render_pragmas:function(a){if(!this.includes("%",a))return a; 2 | var b=this;return a.replace(RegExp(this.otag+"%([\\w-]+) ?([\\w]+=[\\w]+)?"+this.ctag),function(c,d,e){if(!b.pragmas_implemented[d])throw{message:"This implementation of mustache doesn't understand the '"+d+"' pragma"};b.pragmas[d]={};if(e){c=e.split("=");b.pragmas[d][c[0]]=c[1]}return""})},render_partial:function(a,b,c){a=this.trim(a);if(!c||c[a]===undefined)throw{message:"unknown_partial '"+a+"'"};if(typeof b[a]!="object")return this.render(c[a],b,c,true);return this.render(c[a],b[a],c,true)},render_section:function(a, 3 | b,c){if(!this.includes("#",a)&&!this.includes("^",a))return a;var d=this;return a.replace(RegExp(this.otag+"(\\^|\\#)\\s*(.+)\\s*"+this.ctag+"\n*([\\s\\S]+?)"+this.otag+"\\/\\s*\\2\\s*"+this.ctag+"\\s*","mg"),function(e,j,k,h){e=d.find(k,b);if(j=="^")return!e||d.is_array(e)&&e.length===0?d.render(h,b,c,true):"";else if(j=="#")return d.is_array(e)?d.map(e,function(g){return d.render(h,d.create_context(g),c,true)}).join(""):d.is_object(e)?d.render(h,d.create_context(e),c,true):typeof e==="function"? 4 | e.call(b,h,function(g){return d.render(g,b,c,true)}):e?d.render(h,b,c,true):""})},render_tags:function(a,b,c,d){var e=this,j=function(){return RegExp(e.otag+"(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?"+e.ctag+"+","g")},k=j(),h=function(o,m,l){switch(m){case "!":return"";case "=":e.set_delimiters(l);k=j();return"";case ">":return e.render_partial(l,b,c);case "{":return e.find(l,b);default:return e.escape(e.find(l,b))}};a=a.split("\n");for(var g=0;g\\]/g,function(b){switch(b){case "&":return"&";case "\\":return"\\\\";case '"':return'"';case "<":return"<";case ">":return">";default:return b}})},create_context:function(a){if(this.is_object(a))return a;else{var b=".";if(this.pragmas["IMPLICIT-ITERATOR"])b=this.pragmas["IMPLICIT-ITERATOR"].iterator;var c={};c[b]=a;return c}}, 7 | is_object:function(a){return a&&typeof a=="object"},is_array:function(a){return Object.prototype.toString.call(a)==="[object Array]"},trim:function(a){return a.replace(/^\s*|\s*$/g,"")},map:function(a,b){if(typeof a.map=="function")return a.map(b);else{for(var c=[],d=a.length,e=0;e/g,">").replace(/"/g, 9 | """)},set:function(a,b){b||(b={});if(!a)return this;if(a.attributes)a=a.attributes;var c=this.attributes,d=this._escapedAttributes;if(!b.silent&&this.validate&&!this._performValidation(a,b))return false;if("id"in a)this.id=a.id;for(var g in a){var i=a[g];if(!f.isEqual(c[g],i)){c[g]=i;delete d[g];if(!b.silent){this._changed=true;this.trigger("change:"+g,this,i,b)}}}!b.silent&&this._changed&&this.change(b);return this},unset:function(a,b){b||(b={});var c={};c[a]=void 0;if(!b.silent&&this.validate&& 10 | !this._performValidation(c,b))return false;delete this.attributes[a];delete this._escapedAttributes[a];if(!b.silent){this._changed=true;this.trigger("change:"+a,this,void 0,b);this.change(b)}return this},clear:function(a){a||(a={});var b=this.attributes,c={};for(attr in b)c[attr]=void 0;if(!a.silent&&this.validate&&!this._performValidation(c,a))return false;this.attributes={};this._escapedAttributes={};if(!a.silent){this._changed=true;for(attr in b)this.trigger("change:"+attr,this,void 0,a);this.change(a)}return this}, 11 | fetch:function(a){a||(a={});var b=this,c=j(a.error,b,a);(this.sync||e.sync)("read",this,function(d){if(!b.set(b.parse(d),a))return false;a.success&&a.success(b,d)},c);return this},save:function(a,b){b||(b={});if(a&&!this.set(a,b))return false;var c=this,d=j(b.error,c,b),g=this.isNew()?"create":"update";(this.sync||e.sync)(g,this,function(i){if(!c.set(c.parse(i),b))return false;b.success&&b.success(c,i)},d);return this},destroy:function(a){a||(a={});var b=this,c=j(a.error,b,a);(this.sync||e.sync)("delete", 12 | this,function(d){b.collection&&b.collection.remove(b);a.success&&a.success(b,d)},c);return this},url:function(){var a=k(this.collection);if(this.isNew())return a;return a+(a.charAt(a.length-1)=="/"?"":"/")+this.id},parse:function(a){return a},clone:function(){return new this.constructor(this)},isNew:function(){return!this.id},change:function(a){this.trigger("change",this,a);this._previousAttributes=f.clone(this.attributes);this._changed=false},hasChanged:function(a){if(a)return this._previousAttributes[a]!= 13 | this.attributes[a];return this._changed},changedAttributes:function(a){a||(a=this.attributes);var b=this._previousAttributes,c=false,d;for(d in a)if(!f.isEqual(b[d],a[d])){c=c||{};c[d]=a[d]}return c},previous:function(a){if(!a||!this._previousAttributes)return null;return this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},_performValidation:function(a,b){var c=this.validate(a);if(c){b.error?b.error(this,c):this.trigger("error",this,c,b);return false}return true}}); 14 | e.Collection=function(a,b){b||(b={});if(b.comparator){this.comparator=b.comparator;delete b.comparator}this._boundOnModelEvent=f.bind(this._onModelEvent,this);this._reset();a&&this.refresh(a,{silent:true});this.initialize(a,b)};f.extend(e.Collection.prototype,e.Events,{model:e.Model,initialize:function(){},toJSON:function(){return this.map(function(a){return a.toJSON()})},add:function(a,b){if(f.isArray(a))for(var c=0,d=a.length;c').hide().appendTo("body")[0].contentWindow; 22 | "onhashchange"in window&&!a?h(window).bind("hashchange",this.checkUrl):setInterval(this.checkUrl,this.interval);return this.loadUrl()},route:function(a,b){this.handlers.push({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();if(a==this.fragment&&this.iframe)a=this.getFragment(this.iframe.location);if(a==this.fragment||a==decodeURIComponent(this.fragment))return false;if(this.iframe)window.location.hash=this.iframe.location.hash=a;this.loadUrl()},loadUrl:function(){var a=this.fragment= 23 | this.getFragment();return f.any(this.handlers,function(b){if(b.route.test(a)){b.callback(a);return true}})},saveLocation:function(a){a=(a||"").replace(l,"");if(this.fragment!=a){window.location.hash=this.fragment=a;if(this.iframe&&a!=this.getFragment(this.iframe.location)){this.iframe.document.open().close();this.iframe.location.hash=a}}}});e.View=function(a){this._configure(a||{});this._ensureElement();this.delegateEvents();this.initialize(a)};var q=/^(\w+)\s*(.*)$/;f.extend(e.View.prototype,e.Events, 24 | {tagName:"div",$:function(a){return h(a,this.el)},initialize:function(){},render:function(){return this},remove:function(){h(this.el).remove();return this},make:function(a,b,c){a=document.createElement(a);b&&h(a).attr(b);c&&h(a).html(c);return a},delegateEvents:function(a){if(a||(a=this.events)){h(this.el).unbind();for(var b in a){var c=a[b],d=b.match(q),g=d[1];d=d[2];c=f.bind(this[c],this);d===""?h(this.el).bind(g,c):h(this.el).delegate(d,g,c)}}},_configure:function(a){if(this.options)a=f.extend({}, 25 | this.options,a);if(a.model)this.model=a.model;if(a.collection)this.collection=a.collection;if(a.el)this.el=a.el;if(a.id)this.id=a.id;if(a.className)this.className=a.className;if(a.tagName)this.tagName=a.tagName;this.options=a},_ensureElement:function(){if(!this.el){var a={};if(this.id)a.id=this.id;if(this.className)a["class"]=this.className;this.el=this.make(this.tagName,a)}}});var m=function(a,b){var c=r(this,a,b);c.extend=m;return c};e.Model.extend=e.Collection.extend=e.Controller.extend=e.View.extend= 26 | m;var s={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};e.sync=function(a,b,c,d){var g=s[a];a=a==="create"||a==="update"?JSON.stringify(b.toJSON()):null;b={url:k(b),type:g,contentType:"application/json",data:a,dataType:"json",processData:false,success:c,error:d};if(e.emulateJSON){b.contentType="application/x-www-form-urlencoded";b.processData=true;b.data=a?{model:a}:{}}if(e.emulateHTTP)if(g==="PUT"||g==="DELETE"){if(e.emulateJSON)b.data._method=g;b.type="POST";b.beforeSend=function(i){i.setRequestHeader("X-HTTP-Method-Override", 27 | g)}}h.ajax(b)};var n=function(){},r=function(a,b,c){var d;d=b&&b.hasOwnProperty("constructor")?b.constructor:function(){return a.apply(this,arguments)};n.prototype=a.prototype;d.prototype=new n;b&&f.extend(d.prototype,b);c&&f.extend(d,c);d.prototype.constructor=d;d.__super__=a.prototype;return d},k=function(a){if(!(a&&a.url))throw Error("A 'url' property or function must be specified");return f.isFunction(a.url)?a.url():a.url},j=function(a,b,c){return function(d){a?a(b,d):b.trigger("error",b,d,c)}}})(); 28 | -------------------------------------------------------------------------------- /htdocs/js/controllers.js: -------------------------------------------------------------------------------- 1 | // Controllers used by search.metacpan.org 2 | 3 | var Metacpan = Backbone.Controller.extend({ 4 | 5 | routes: { 6 | "": "home", 7 | "/author/:query": "showauthor", 8 | "/search/:type/:query": "search", 9 | "/showpod/:query": "showpod", 10 | "/showsrc/:query": "showsrc", 11 | "/dist/:query": "showdist" 12 | }, 13 | 14 | apiUrl: '/api', 15 | 16 | initialize: function() { 17 | 18 | $("#main_content a").click(function(e) { 19 | e.preventDefault; 20 | }); 21 | 22 | $.ajaxSetup({ 23 | cache: false, 24 | dataType: 'json' 25 | }); 26 | 27 | // some global defaults for the DataTable plugin 28 | $.extend($.fn.dataTableExt.oJUIClasses, { 29 | sStripOdd: 'ui-state-active row_overrides', 30 | sStripEven: 'ui-state-default row_overrides' 31 | }); 32 | 33 | // sets up some persistant cookie variables 34 | if ( $.cookie('tableDisplayLength') == '' || Number($.cookie('tableDisplayLength')) < 10 ) { 35 | $.cookie('tableDisplayLength', 10); 36 | } 37 | if ( $.cookie('jquery-ui-theme') == '' || $.cookie('jquery-ui-theme') == null ) { 38 | $.cookie('jquery-ui-theme', 'metaCPAN'); 39 | } 40 | 41 | SearchBoxView = new SearchBox(); 42 | SearchBoxView.render(); 43 | ModuleResultsView = new ModuleResults(); 44 | ModuleResultsView.render(); 45 | ModuleDetailsView = new ModuleDetails(); 46 | ModuleDetailsView.render(); 47 | SourceDetailsView = new SourceDetails(); 48 | SourceDetailsView.render(); 49 | AuthorDetailsView = new AuthorDetails(); 50 | AuthorDetailsView.render(); 51 | DistResultsView = new DistResults(); 52 | DistResultsView.render(); 53 | DistDetailsView = new DistDetails(); 54 | DistDetailsView.render(); 55 | HomeView = new Home(); 56 | HomeView.render(); 57 | 58 | _.bindAll(this, [ "enableBackButtons" ]); 59 | }, 60 | 61 | home: function() { 62 | debug("Action: home page"); 63 | 64 | document.title = 'Welcome to search.metacpan.org' 65 | $("#changes").load("/CHANGES"); 66 | this.saveLocation(""); 67 | HomeView.show(); 68 | }, 69 | 70 | search: function(type, query) { 71 | query = unescape(query); 72 | debug("Action: search"); 73 | debug("Type : " + type); 74 | debug("Query: " + query); 75 | 76 | var my = this; 77 | 78 | document.title = 'Search results for: ' + query + ' - search.metacpan.org'; 79 | 80 | SearchBoxView.searchType(type); 81 | SearchBoxView.updateQuery(query); 82 | 83 | switch(type) { 84 | 85 | case 'module': 86 | this.saveLocation("/search/module/" + query); 87 | SearchBoxView.updateTweet(); 88 | SearchBoxView.loader('show'); 89 | 90 | if ( ModuleResultsView.current() === query ) { 91 | ModuleResultsView.show(); 92 | SearchBoxView.loader('hide'); 93 | } else { 94 | ModuleResultsView.current(query); 95 | $(".metacpanView").fadeOut(200); 96 | query = query.replace(/::/, " "); 97 | $.ajax({ 98 | url: 'http://0.0.0.0:3000/', 99 | type: 'post', 100 | processData: false, 101 | data: '{ "size": "50", "query": { "field":{"file.documentation.analyzed":"' + query.toLowerCase() + '"}}, "filter":{"term":{"file.status":"latest"}} }', 102 | success: function(res) { 103 | debug(res); 104 | $("#module_results_table").dataTable().fnClearTable(); 105 | ModuleResultsView.update(res, true); 106 | SearchBoxView.loader('hide'); 107 | }, 108 | error: function(xhr,status,error) { 109 | debug(xhr); 110 | debug(status); 111 | debug(error); 112 | $("#module_results_table").dataTable().fnClearTable() 113 | ModuleResultsView.show(); 114 | SearchBoxView.loader('hide'); 115 | } 116 | }); 117 | } 118 | break; 119 | case 'dist': 120 | this.saveLocation("/search/dist/" + query); 121 | SearchBoxView.updateTweet(); 122 | SearchBoxView.loader('show'); 123 | 124 | if ( DistResultsView.current() === query ) { 125 | DistResultsView.show(); 126 | SearchBoxView.loader('hide'); 127 | } else { 128 | DistResultsView.current(query); 129 | $(".metacpanView").fadeOut(200); 130 | $.ajax({ 131 | url: my.apiUrl + '/release/_search', 132 | type: 'post', 133 | processData: false, 134 | data: '{ "size": "500", "query": { "field": { "release.name.analyzed":"' + query.toLowerCase() + '"}}, "filter":{"term":{"status":"latest"}} }', 135 | success: function(res) { 136 | debug(res); 137 | $("#dist_results_table").dataTable().fnClearTable(); 138 | DistResultsView.update(res, true); 139 | SearchBoxView.loader('hide'); 140 | }, 141 | error: function(xhr,status,error) { 142 | debug(xhr); 143 | debug(status); 144 | debug(error); 145 | $("#dist_results_table").dataTable().fnClearTable() 146 | DistResultsView.show(); 147 | SearchBoxView.loader('hide'); 148 | } 149 | }); 150 | } 151 | break; 152 | default: 153 | debug('<< ' + type + ' >> is not a valid search type.' ); 154 | SearchBoxView.loader('hide'); 155 | 156 | } 157 | 158 | }, 159 | 160 | showpod: function(query) { 161 | query = unescape(query); 162 | debug("Action: showpod"); 163 | debug("Query: " + query); 164 | 165 | var my = this; 166 | 167 | document.title = query + ' - search.metacpan.org'; 168 | 169 | SearchBoxView.searchType('module'); 170 | SearchBoxView.updateQuery(query); 171 | 172 | ModuleDetailsView.show(); 173 | 174 | if ( ModuleDetailsView.current() === query ) { 175 | var fn = (function() { ModuleDetailsView.showPod(); }); 176 | setTimeout(fn, 410); 177 | } else { 178 | $.ajax({ 179 | url: my.apiUrl + '/module/' + query, 180 | success: function(res) { 181 | res["_source"] = res; 182 | MetacpanController.saveLocation("/showpod/" + res._source.documentation); 183 | SearchBoxView.updateTweet(); 184 | if ( ModuleDetailsView.current() === res._source.documentation ) { 185 | ModuleDetailsView.showPod(); 186 | } else { 187 | ModuleDetailsView.current(res._source.documentation); 188 | $.ajax({ 189 | url: my.apiUrl + '/pod/' + res._source.documentation + '?content-type=text/html', 190 | dataType: 'text', 191 | success: function(pod) { 192 | if ( pod ) { 193 | $.ajax({ 194 | url: my.apiUrl + '/author/' + res._source.author, 195 | success: function(author) { 196 | ModuleDetailsView.updatePod(res, pod, author); 197 | }, 198 | error: function() { 199 | ModuleDetailsView.updatePod(res, pod); 200 | } 201 | }); 202 | } else { 203 | ModuleDetailsView.noPod("no pod could be found for << " + res._source.name + " >>"); 204 | } 205 | }, 206 | error: function(xhr,status,error) { 207 | debug(xhr); 208 | debug(status); 209 | debug(error); 210 | ModuleDetailsView.noPod("no pod could be found for << " + res._source.name + " >>"); 211 | } 212 | }); 213 | } 214 | }, 215 | error: function(xhr, error, status) { 216 | debug(xhr); 217 | debug(status); 218 | debug(error); 219 | if ( ModuleDetailsView.current() === query ) { 220 | MetacpanController.saveLocation("/showpod/" + query); 221 | SearchBoxView.updateTweet(); 222 | var fn = (function() { ModuleDetailsView.showPod(); }); 223 | setTimeout(fn, 205); 224 | } else { 225 | ModuleDetailsView.current(query); 226 | MetacpanController.saveLocation("/showpod/" + query); 227 | SearchBoxView.updateTweet(); 228 | var fn = (function() { ModuleDetailsView.noPod("no module found for << " + query + " >>"); }); 229 | setTimeout(fn, 205); 230 | } 231 | } 232 | }); 233 | } 234 | 235 | }, 236 | 237 | showsrc: function(query) { 238 | query = unescape(query); 239 | debug("Action: showsrc"); 240 | debug("Query: " + query); 241 | 242 | var my = this; 243 | 244 | document.title = 'Source: ' + query + ' - search.metacpan.org'; 245 | 246 | SearchBoxView.searchType('module'); 247 | SearchBoxView.updateQuery(query); 248 | 249 | SourceDetailsView.show(); 250 | 251 | if ( SourceDetailsView.current() === query ) { 252 | var fn = (function() { SourceDetailsView.showSource(); }); 253 | setTimeout(fn, 410); 254 | } else { 255 | $.ajax({ 256 | url: my.apiUrl + '/module/' + query, 257 | success: function(res) { 258 | debug(res); 259 | res["_source"] = res; 260 | MetacpanController.saveLocation("/showsrc/" + res._source.documentation); 261 | SearchBoxView.updateTweet(); 262 | if ( SourceDetailsView.current() === res._source.documentation ) { 263 | SourceDetailsView.showSource(); 264 | } else { 265 | SourceDetailsView.current(res._source.documentation); 266 | var url = ["/source", res._source.author, res._source.release, res._source.path].join("/"); 267 | $.ajax({ 268 | url: url, 269 | dataType: 'text', 270 | processData: false, 271 | success: function(source) { 272 | if ( typeof(source) != 'undefined') { 273 | SourceDetailsView.showSource(source, res._source.author); 274 | } else { 275 | SourceDetailsView.noSource("no source could be found for << " + res._source.name + " >>"); 276 | } 277 | }, 278 | error: function(xhr,status,error) { 279 | debug('Failed retrieving source:'); 280 | debug(xhr); 281 | debug(status); 282 | debug(error); 283 | SourceDetailsView.noSource("no source could be found for << " + res._source.name + " >>"); 284 | } 285 | }); 286 | } 287 | }, 288 | error: function(xhr, error, status) { 289 | debug(xhr); 290 | debug(status); 291 | debug(error); 292 | if ( SourceDetailsView.current() === query ) { 293 | MetacpanController.saveLocation("/showsrc/" + query); 294 | SearchBoxView.updateTweet(); 295 | var fn = (function() { SourceDetailsView.showSource(); }); 296 | setTimeout(fn, 205); 297 | } else { 298 | SourceDetailsView.current(query); 299 | MetacpanController.saveLocation("/showsrc/" + query); 300 | SearchBoxView.updateTweet(); 301 | var fn = (function() { SourceDetailsView.noSource("no module found for << " + query + " >>"); }); 302 | setTimeout(fn, 205); 303 | } 304 | } 305 | }); 306 | } 307 | 308 | }, 309 | 310 | showauthor: function(query) { 311 | query = unescape(query); 312 | debug("Action: showauthor"); 313 | debug("Query: " + query); 314 | 315 | var my = this; 316 | 317 | var author = query.toUpperCase(); 318 | 319 | document.title = author + ' - search.metacpan.org'; 320 | 321 | MetacpanController.saveLocation("/author/" + author); 322 | SearchBoxView.updateTweet(); 323 | 324 | SearchBoxView.searchType('author'); 325 | SearchBoxView.updateQuery(query); 326 | 327 | AuthorDetailsView.show(); 328 | 329 | if ( AuthorDetailsView.current() === query ) { 330 | debug("Author info already retrieved."); 331 | var fn = (function() { AuthorDetailsView.showAuthor(); }); 332 | setTimeout(fn, 410); 333 | } else { 334 | AuthorDetailsView.current(query); 335 | var fn = (function() { 336 | $.ajax({ 337 | url: my.apiUrl + '/author/' + author, 338 | success: function(res) { 339 | debug(res); 340 | AuthorDetailsView.updateAuthor(res); 341 | $.ajax({ 342 | url: my.apiUrl + '/release/_search', 343 | processData: false, 344 | type: 'post', 345 | data: '{ "query": { "term": { "author": "' + author + '" } }, "filter":{"term":{"status":"latest"}}, "size": 1000 }', 346 | success: function(results) { 347 | debug('Succeeded dist search for author: ' + author); 348 | debug(results); 349 | AuthorDetailsView.update(results); 350 | }, 351 | error: function(xhr,status,error) { 352 | debug('Failed dist search for author: ' + author); 353 | debug(xhr); 354 | debug(status); 355 | debug(error); 356 | AuthorDetailsView.update(); 357 | } 358 | }); 359 | }, 360 | error: function(xhr, error, status) { 361 | debug('Failed author search for PAUSEID << ' + author + ' >>'); 362 | debug(xhr); 363 | debug(status); 364 | debug(error); 365 | AuthorDetailsView.noAuthor("no author info found for PAUSEID << " + author + " >>"); 366 | } 367 | }); 368 | }); 369 | setTimeout(fn, 410); 370 | } 371 | 372 | }, 373 | 374 | showdist: function(query) { 375 | query = unescape(query); 376 | debug("Action: showdist"); 377 | debug("Query: " + query); 378 | 379 | var my = this; 380 | 381 | document.title = 'Distribution: ' + query + ' - search.metacpan.org'; 382 | 383 | MetacpanController.saveLocation("/dist/" + query); 384 | SearchBoxView.updateTweet(); 385 | 386 | SearchBoxView.searchType('dist'); 387 | SearchBoxView.updateQuery(query); 388 | 389 | DistDetailsView.show(); 390 | 391 | if ( DistDetailsView.current() === query ) { 392 | var fn = (function() { DistDetailsView.showDist(); }); 393 | setTimeout(fn, 410); 394 | } else { 395 | DistDetailsView.current(query); 396 | var fn = (function() { 397 | $.ajax({ 398 | url: my.apiUrl + '/release/_search', 399 | type: 'post', 400 | data: '{"size":1,"query":{"term":{"release.name":"' + query + '"}}}', 401 | success: function(res) { 402 | res = res.hits.hits[0]._source; 403 | debug(res); 404 | DistDetailsView.updateDist(res); 405 | $.ajax({ 406 | url: my.apiUrl + '/file/_search', 407 | type: 'post', 408 | processData: false, 409 | data: '{ "size": "1000", "query":{"match_all":{}},"filter": { "and":[{"exists":{"field":"file.documentation"}},{"term": { "file.release": "' + query + '" } },{"term": { "file.indexed": true } }] } }', 410 | success: function(results) { 411 | debug('Succeeded module search for dist: ' + query); 412 | debug(results); 413 | DistDetailsView.update(results); 414 | }, 415 | error: function(xhr,status,error) { 416 | debug('Failed module search for dist: ' + query); 417 | debug(xhr); 418 | debug(status); 419 | debug(error); 420 | DistDetailsView.update(); 421 | } 422 | }); 423 | }, 424 | error: function(xhr, error, status) { 425 | debug('Failed distrbution search for dist: ' + query); 426 | debug(xhr); 427 | debug(status); 428 | debug(error); 429 | DistDetailsView.noDist("No distribution info found for << " + query + " >>"); 430 | } 431 | }); 432 | }); 433 | setTimeout(fn, 410); 434 | } 435 | 436 | }, 437 | 438 | enableBackButtons: function() { 439 | $(".back_button").button({ 440 | icons: { primary: 'ui-icon-arrowreturnthick-1-w' }, 441 | text: false 442 | }).click(function() { 443 | history.back() 444 | }); 445 | } 446 | 447 | }); 448 | -------------------------------------------------------------------------------- /htdocs/js/encoder.js: -------------------------------------------------------------------------------- 1 | Encoder = { 2 | 3 | // When encoding do we convert characters into html or numerical entities 4 | EncodeType : "entity", // entity OR numerical 5 | 6 | isEmpty : function(val){ 7 | if(val){ 8 | return ((val===null) || val.length==0 || /^\s+$/.test(val)); 9 | }else{ 10 | return true; 11 | } 12 | }, 13 | // Convert HTML entities into numerical entities 14 | HTML2Numerical : function(s){ 15 | var arr1 = new Array(' ','¡','¢','£','¤','¥','¦','§','¨','©','ª','«','¬','­','®','¯','°','±','²','³','´','µ','¶','·','¸','¹','º','»','¼','½','¾','¿','à','á','â','ã','Ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð','ñ','ò','ó','ô','õ','Ö','×','ø','ù','ú','û','Ü','ý','þ','ß','à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð','ñ','ò','ó','ô','õ','ö','÷','Ø','ù','ú','û','ü','ý','þ','ÿ','"','&','<','>','œ','œ','š','š','ÿ','ˆ','˜',' ',' ',' ','‌','‍','‎','‏','–','—','‘','’','‚','“','”','„','†','†','‰','‹','›','€','ƒ','α','β','γ','δ','ε','ζ','η','θ','ι','κ','λ','μ','ν','ξ','ο','π','ρ','σ','τ','υ','φ','χ','ψ','ω','α','β','γ','δ','ε','ζ','η','θ','ι','κ','λ','μ','ν','ξ','ο','π','ρ','ς','σ','τ','υ','φ','χ','ψ','ω','ϑ','ϒ','ϖ','•','…','′','′','‾','⁄','℘','ℑ','ℜ','™','ℵ','←','↑','→','↓','↔','↵','←','↑','→','↓','↔','∀','∂','∃','∅','∇','∈','∉','∋','∏','∑','−','∗','√','∝','∞','∠','∧','∨','∩','∪','∫','∴','∼','≅','≈','≠','≡','≤','≥','⊂','⊃','⊄','⊆','⊇','⊕','⊗','⊥','⋅','⌈','⌉','⌊','⌋','⟨','⟩','◊','♠','♣','♥','♦'); 16 | var arr2 = new Array(' ','¡','¢','£','¤','¥','¦','§','¨','©','ª','«','¬','­','®','¯','°','±','²','³','´','µ','¶','·','¸','¹','º','»','¼','½','¾','¿','À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï','Ð','Ñ','Ò','Ó','Ô','Õ','Ö','×','Ø','Ù','Ú','Û','Ü','Ý','Þ','ß','à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð','ñ','ò','ó','ô','õ','ö','÷','ø','ù','ú','û','ü','ý','þ','ÿ','"','&','<','>','Œ','œ','Š','š','Ÿ','ˆ','˜',' ',' ',' ','‌','‍','‎','‏','–','—','‘','’','‚','“','”','„','†','‡','‰','‹','›','€','ƒ','Α','Β','Γ','Δ','Ε','Ζ','Η','Θ','Ι','Κ','Λ','Μ','Ν','Ξ','Ο','Π','Ρ','Σ','Τ','Υ','Φ','Χ','Ψ','Ω','α','β','γ','δ','ε','ζ','η','θ','ι','κ','λ','μ','ν','ξ','ο','π','ρ','ς','σ','τ','υ','φ','χ','ψ','ω','ϑ','ϒ','ϖ','•','…','′','″','‾','⁄','℘','ℑ','ℜ','™','ℵ','←','↑','→','↓','↔','↵','⇐','⇑','⇒','⇓','⇔','∀','∂','∃','∅','∇','∈','∉','∋','∏','∑','−','∗','√','∝','∞','∠','∧','∨','∩','∪','∫','∴','∼','≅','≈','≠','≡','≤','≥','⊂','⊃','⊄','⊆','⊇','⊕','⊗','⊥','⋅','⌈','⌉','⌊','⌋','〈','〉','◊','♠','♣','♥','♦'); 17 | return this.swapArrayVals(s,arr1,arr2); 18 | }, 19 | 20 | // Convert Numerical entities into HTML entities 21 | NumericalToHTML : function(s){ 22 | var arr1 = new Array(' ','¡','¢','£','¤','¥','¦','§','¨','©','ª','«','¬','­','®','¯','°','±','²','³','´','µ','¶','·','¸','¹','º','»','¼','½','¾','¿','À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï','Ð','Ñ','Ò','Ó','Ô','Õ','Ö','×','Ø','Ù','Ú','Û','Ü','Ý','Þ','ß','à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð','ñ','ò','ó','ô','õ','ö','÷','ø','ù','ú','û','ü','ý','þ','ÿ','"','&','<','>','Œ','œ','Š','š','Ÿ','ˆ','˜',' ',' ',' ','‌','‍','‎','‏','–','—','‘','’','‚','“','”','„','†','‡','‰','‹','›','€','ƒ','Α','Β','Γ','Δ','Ε','Ζ','Η','Θ','Ι','Κ','Λ','Μ','Ν','Ξ','Ο','Π','Ρ','Σ','Τ','Υ','Φ','Χ','Ψ','Ω','α','β','γ','δ','ε','ζ','η','θ','ι','κ','λ','μ','ν','ξ','ο','π','ρ','ς','σ','τ','υ','φ','χ','ψ','ω','ϑ','ϒ','ϖ','•','…','′','″','‾','⁄','℘','ℑ','ℜ','™','ℵ','←','↑','→','↓','↔','↵','⇐','⇑','⇒','⇓','⇔','∀','∂','∃','∅','∇','∈','∉','∋','∏','∑','−','∗','√','∝','∞','∠','∧','∨','∩','∪','∫','∴','∼','≅','≈','≠','≡','≤','≥','⊂','⊃','⊄','⊆','⊇','⊕','⊗','⊥','⋅','⌈','⌉','⌊','⌋','〈','〉','◊','♠','♣','♥','♦'); 23 | var arr2 = new Array(' ','¡','¢','£','¤','¥','¦','§','¨','©','ª','«','¬','­','®','¯','°','±','²','³','´','µ','¶','·','¸','¹','º','»','¼','½','¾','¿','à','á','â','ã','Ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð','ñ','ò','ó','ô','õ','Ö','×','ø','ù','ú','û','Ü','ý','þ','ß','à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð','ñ','ò','ó','ô','õ','ö','÷','Ø','ù','ú','û','ü','ý','þ','ÿ','"','&','<','>','œ','œ','š','š','ÿ','ˆ','˜',' ',' ',' ','‌','‍','‎','‏','–','—','‘','’','‚','“','”','„','†','†','‰','‹','›','€','ƒ','α','β','γ','δ','ε','ζ','η','θ','ι','κ','λ','μ','ν','ξ','ο','π','ρ','σ','τ','υ','φ','χ','ψ','ω','α','β','γ','δ','ε','ζ','η','θ','ι','κ','λ','μ','ν','ξ','ο','π','ρ','ς','σ','τ','υ','φ','χ','ψ','ω','ϑ','ϒ','ϖ','•','…','′','′','‾','⁄','℘','ℑ','ℜ','™','ℵ','←','↑','→','↓','↔','↵','←','↑','→','↓','↔','∀','∂','∃','∅','∇','∈','∉','∋','∏','∑','−','∗','√','∝','∞','∠','∧','∨','∩','∪','∫','∴','∼','≅','≈','≠','≡','≤','≥','⊂','⊃','⊄','⊆','⊇','⊕','⊗','⊥','⋅','⌈','⌉','⌊','⌋','⟨','⟩','◊','♠','♣','♥','♦'); 24 | return this.swapArrayVals(s,arr1,arr2); 25 | }, 26 | 27 | 28 | // Numerically encodes all unicode characters 29 | numEncode : function(s){ 30 | 31 | if(this.isEmpty(s)) return ""; 32 | 33 | var e = ""; 34 | for (var i = 0; i < s.length; i++) 35 | { 36 | var c = s.charAt(i); 37 | if (c < " " || c > "~") 38 | { 39 | c = "&#" + c.charCodeAt() + ";"; 40 | } 41 | e += c; 42 | } 43 | return e; 44 | }, 45 | 46 | // HTML Decode numerical and HTML entities back to original values 47 | htmlDecode : function(s){ 48 | 49 | var c,m,d = s; 50 | 51 | if(this.isEmpty(d)) return ""; 52 | 53 | // convert HTML entites back to numerical entites first 54 | d = this.HTML2Numerical(d); 55 | 56 | // look for numerical entities " 57 | arr=d.match(/&#[0-9]{1,5};/g); 58 | 59 | // if no matches found in string then skip 60 | if(arr!=null){ 61 | for(var x=0;x= -32768 && c <= 65535){ 66 | // decode every single match within string 67 | d = d.replace(m, String.fromCharCode(c)); 68 | }else{ 69 | d = d.replace(m, ""); //invalid so replace with nada 70 | } 71 | } 72 | } 73 | 74 | return d; 75 | }, 76 | 77 | // encode an input string into either numerical or HTML entities 78 | htmlEncode : function(s,dbl){ 79 | 80 | if(this.isEmpty(s)) return ""; 81 | 82 | // do we allow double encoding? E.g will & be turned into &amp; 83 | dbl = dbl | false; //default to prevent double encoding 84 | 85 | // if allowing double encoding we do ampersands first 86 | if(dbl){ 87 | if(this.EncodeType=="numerical"){ 88 | s = s.replace(/&/g, "&"); 89 | }else{ 90 | s = s.replace(/&/g, "&"); 91 | } 92 | } 93 | 94 | // convert the xss chars to numerical entities ' " < > 95 | s = this.XSSEncode(s,false); 96 | 97 | if(this.EncodeType=="numerical" || !dbl){ 98 | // Now call function that will convert any HTML entities to numerical codes 99 | s = this.HTML2Numerical(s); 100 | } 101 | 102 | // Now encode all chars above 127 e.g unicode 103 | s = this.numEncode(s); 104 | 105 | // now we know anything that needs to be encoded has been converted to numerical entities we 106 | // can encode any ampersands & that are not part of encoded entities 107 | // to handle the fact that I need to do a negative check and handle multiple ampersands &&& 108 | // I am going to use a placeholder 109 | 110 | // if we don't want double encoded entities we ignore the & in existing entities 111 | if(!dbl){ 112 | s = s.replace(/&#/g,"##AMPHASH##"); 113 | 114 | if(this.EncodeType=="numerical"){ 115 | s = s.replace(/&/g, "&"); 116 | }else{ 117 | s = s.replace(/&/g, "&"); 118 | } 119 | 120 | s = s.replace(/##AMPHASH##/g,"&#"); 121 | } 122 | 123 | // replace any malformed entities 124 | s = s.replace(/&#\d*([^\d;]|$)/g, "$1"); 125 | 126 | if(!dbl){ 127 | // safety check to correct any double encoded & 128 | s = this.correctEncoding(s); 129 | } 130 | 131 | // now do we need to convert our numerical encoded string into entities 132 | if(this.EncodeType=="entity"){ 133 | s = this.NumericalToHTML(s); 134 | } 135 | 136 | return s; 137 | }, 138 | 139 | // Encodes the basic 4 characters used to malform HTML in XSS hacks 140 | XSSEncode : function(s,en){ 141 | if(!this.isEmpty(s)){ 142 | en = en || true; 143 | // do we convert to numerical or html entity? 144 | if(en){ 145 | s = s.replace(/\'/g,"'"); //no HTML equivalent as &apos is not cross browser supported 146 | s = s.replace(/\"/g,"""); 147 | s = s.replace(//g,">"); 149 | }else{ 150 | s = s.replace(/\'/g,"'"); //no HTML equivalent as &apos is not cross browser supported 151 | s = s.replace(/\"/g,"""); 152 | s = s.replace(//g,">"); 154 | } 155 | return s; 156 | }else{ 157 | return ""; 158 | } 159 | }, 160 | 161 | // returns true if a string contains html or numerical encoded entities 162 | hasEncoded : function(s){ 163 | if(/&#[0-9]{1,5};/g.test(s)){ 164 | return true; 165 | }else if(/&[A-Z]{2,6};/gi.test(s)){ 166 | return true; 167 | }else{ 168 | return false; 169 | } 170 | }, 171 | 172 | // will remove any unicode characters 173 | stripUnicode : function(s){ 174 | return s.replace(/[^\x20-\x7E]/g,""); 175 | 176 | }, 177 | 178 | // corrects any double encoded & entities e.g &amp; 179 | correctEncoding : function(s){ 180 | return s.replace(/(&)(amp;)+/,"$1"); 181 | }, 182 | 183 | 184 | // Function to loop through an array swaping each item with the value from another array e.g swap HTML entities with Numericals 185 | swapArrayVals : function(s,arr1,arr2){ 186 | if(this.isEmpty(s)) return ""; 187 | var re; 188 | if(arr1 && arr2){ 189 | //ShowDebug("in swapArrayVals arr1.length = " + arr1.length + " arr2.length = " + arr2.length) 190 | // array lengths must match 191 | if(arr1.length == arr2.length){ 192 | for(var x=0,i=arr1.length;x7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$('