Skip to content

Commit 22f0774

Browse files
committed
rewrite profile page javascript to be bundled, and avoid jquery
1 parent 1fcebb5 commit 22f0774

File tree

7 files changed

+259
-162
lines changed

7 files changed

+259
-162
lines changed

lib/MetaCPAN/Middleware/Static.pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ sub wrap {
5454
js/cpan.js
5555
js/github.js
5656
js/dropdown.js
57+
js/profile.js
5758
js/recaptcha.js
5859
js/search.js
5960
modules/bootstrap-v3.4.1/js/dropdown.js

lib/MetaCPAN/Web/Model/API/Author.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ my $profile_data = {
151151
},
152152
hackerrank => {
153153
name => 'HackerRank',
154-
url_format => 'https://www.hackerrank.com/%s',
154+
url_format => 'https://www.hackerrank.com/profile/%s',
155155
},
156156
hackthissite => {
157157
name => 'HackThisSite',

lib/MetaCPAN/Web/Model/API/User.pm

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,17 @@ sub update_profile {
6262

6363
sub get_profile {
6464
my ( $self, $token ) = @_;
65-
$self->request( '/user/profile', undef, { access_token => $token } );
65+
$self->request( '/user/profile', undef, { access_token => $token } )
66+
->then( sub {
67+
my $data = shift;
68+
for my $field (qw(email website)) {
69+
my $value = $data->{$field}
70+
or next;
71+
$data->{$field} = [$value]
72+
if !ref $value;
73+
}
74+
return $data;
75+
} );
6676
}
6777

6878
sub add_favorite {

root/account/profile.tx

Lines changed: 89 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</div>
99
%% }
1010
%% else {
11-
<form method="POST" action="" class="form-horizontal" role="form" accept-charset="utf-8">
11+
<form method="POST" action="" class="profile-form form-horizontal" role="form" accept-charset="utf-8">
1212
<input type="hidden" name="utf8" value="🐪" />
1313
%% if $errors {
1414
<fieldset><legend style="color: #600">Errors</legend>
@@ -58,19 +58,23 @@
5858
<div class="form-group">
5959
<label class="col-sm-4 col-md-4 control-label">Email</label>
6060
<div class="col-sm-8 col-md-6">
61-
<div class="input-group">
62-
<input type="email" class="form-control" name="email" value="[% $author.email.0 %]" />
63-
<span class="input-group-btn">
64-
<button class="btn btn-primary search-btn" type="button" onclick="return addField('email')">add</button>
65-
</span>
61+
<div class="field-container">
62+
<div class="input-group">
63+
<input type="email" class="form-control" name="email" value="[% $author.email.0 %]" />
64+
<span class="input-group-btn">
65+
<button class="btn btn-primary search-btn add-field" type="button" data-field-type="email">add</button>
66+
</span>
67+
</div>
6668
</div>
6769
%% for $author.email -> $email {
6870
%% if $~email.is_first { next }
69-
<div class="input-group">
70-
<input type="email" class="form-control" name="email" value="[% $email %]" />
71-
<span class="input-group-btn">
72-
<button class="btn btn-primary search-btn" type="button" onclick="return removeDiv(this)">remove</button>
73-
</span>
71+
<div class="field-container">
72+
<div class="input-group">
73+
<input type="email" class="form-control" name="email" value="[% $email %]" />
74+
<span class="input-group-btn">
75+
<button class="btn btn-primary search-btn remove-field" type="button">remove</button>
76+
</span>
77+
</div>
7478
</div>
7579
%% }
7680
</div>
@@ -80,19 +84,23 @@
8084
<div class="form-group">
8185
<label class="col-sm-4 col-md-4 control-label">Website</label>
8286
<div class="col-sm-8 col-md-6">
83-
<div class="input-group">
84-
<input type="url" class="form-control" name="website" value="[% $author.website.0 %]" />
85-
<span class="input-group-btn">
86-
<button class="btn btn-primary search-btn" type="button" onclick="return addField('website')">add</button>
87-
</span>
87+
<div class="field-container">
88+
<div class="input-group">
89+
<input type="url" class="form-control" name="website" value="[% $author.website.0 %]" />
90+
<span class="input-group-btn">
91+
<button class="btn btn-primary search-btn add-field" data-field-type="website" type="button">add</button>
92+
</span>
93+
</div>
8894
</div>
8995
%% for $author.website -> $website {
9096
%% if $~website.is_first { next }
91-
<div class="input-group">
92-
<input type="url" class="form-control" name="website" value="[% $website %]" />
93-
<span class="input-group-btn">
94-
<button class="btn btn-primary search-btn" type="button" href="" onclick="return removeDiv(this)">remove</a></button>
95-
</span>
97+
<div class="field-container">
98+
<div class="input-group">
99+
<input type="url" class="form-control" name="website" value="[% $website %]" />
100+
<span class="input-group-btn">
101+
<button class="btn btn-primary search-btn remove-field" type="button" href="">raemove</a></button>
102+
</span>
103+
</div>
96104
</div>
97105
%% }
98106
</div>
@@ -173,7 +181,7 @@
173181
<input class="input-small form-control" type="text" placeholder="Latitude" name="latitude" value="[% $author.location.0 %]" />
174182
<input class="input-small form-control" type="text" placeholder="Longitude" name="longitude" value="[% $author.location.1 %]" />
175183
<span class="input-group-btn">
176-
<button class="btn btn-primary search-btn" type="button" onclick="return fillLocation()">locate me</button>
184+
<button class="btn btn-primary search-btn fill-location" type="button">locate me</button>
177185
</span>
178186
</div>
179187
</div>
@@ -188,48 +196,47 @@
188196
<div class="form-group profile">
189197
<label class="col-sm-4 col-md-4"></label>
190198
<div class="col-sm-8 col-md-6">
191-
<select class="form-control" onchange="return addProfile(this)">
199+
<select class="form-control add-profile">
192200
<option>Add Profile</option>
193201
%% for $profiles.kv() -> $profile {
194-
%% my $option_value = {
195-
%% id => $profile.key,
196-
%% name => $profile.value.name,
197-
%% url => $profile.value.url_format,
198-
%% };
199-
<option value="[% $option_value.json() %]">[% $profile.value.name %]</option>
202+
<option value="[% $profile.key %]" data-title="[% $profile.value.name %]" data-url-format="[ $profile.value.url_format %]">[% $profile.value.name %]</option>
200203
%% }
201204
<option value="">Custom...</option>
202205
</select>
203206
</div>
204207
</div>
205208
<div id="metacpan_profiles" class="profiles">
206-
<div class="form-group profile profile-metacpan" title="You can use your user id with other services so they can retrieve information from your profile or your favorites here on metacpan.">
207-
<label class="col-sm-4 col-md-4 control-label">metacpan</label>
208-
<div class="col-sm-8 col-md-6">
209-
<input type="text" class="form-control" value="[% $author.user %]" disabled="disabled" />
209+
<div class="profile-container">
210+
<div class="form-group profile profile-metacpan" title="You can use your user id with other services so they can retrieve information from your profile or your favorites here on metacpan.">
211+
<label class="col-sm-4 col-md-4 control-label">metacpan</label>
212+
<div class="col-sm-8 col-md-6">
213+
<input type="text" class="form-control" value="[% $author.user %]" disabled="disabled" />
214+
</div>
210215
</div>
211216
</div>
212217
%% for $author.profile.sort(-> $a, $b { $a.name cmp $b.name }) -> $profile {
213218
%% my $known = $profiles[$profile.name];
214-
<div class="form-group [% if $known { %]profile profile-[% $profile.name %][% } %]">
215-
<label class="col-sm-4 col-md-4 control-label">
216-
%% if $known {
217-
[% $known.name %]
218-
<input type="hidden" name="profile.name" value="[% $profile.name %]" />
219-
%% }
220-
%% else {
221-
<input class="input-small" type="text" class="form-control" name="profile.name" value="[% $profile.name %]">
222-
%% }
223-
</label>
224-
<div class="col-sm-8 col-md-6">
225-
<div class="input-group">
226-
<input class="small form-control" type="text" class="form-control" name="profile.id" value="[% $profile.id %]" />
227-
<span class="input-group-btn">
228-
<a href="" class="btn btn-danger remove" onclick="return removeDiv(this.parentNode.parentNode.parentNode)"><i class="fa fa-trash-alt"></i> remove</a>
219+
<div class="profile-container">
220+
<div class="form-group [% if $known { %]profile profile-[% $profile.name %][% } %]">
221+
<label class="col-sm-4 col-md-4 control-label">
229222
%% if $known {
230-
<a href="" class="btn btn-primary search-btn" target="_blank" tmpl="[% $known.url_format %]" onclick="return rewriteURL(this)"><i class="fa fa-check-square"></i> check</a>
231-
</span>
223+
[% $known.name %]
224+
<input type="hidden" name="profile.name" value="[% $profile.name %]" />
232225
%% }
226+
%% else {
227+
<input class="input-small" type="text" class="form-control" name="profile.name" value="[% $profile.name %]">
228+
%% }
229+
</label>
230+
<div class="col-sm-8 col-md-6">
231+
<div class="input-group">
232+
<input class="small form-control" type="text" class="form-control" name="profile.id" value="[% $profile.id %]" />
233+
<span class="input-group-btn">
234+
<a href="" class="btn btn-danger remove-profile"><i class="fa fa-trash-alt"></i> remove</a>
235+
%% if $known {
236+
<a href="" class="btn btn-primary search-btn check-url" target="_blank" data-url-template="[% $known.url_format %]"><i class="fa fa-check-square"></i> check</a>
237+
</span>
238+
%% }
239+
</div>
233240
</div>
234241
</div>
235242
</div>
@@ -239,106 +246,45 @@
239246
</div>
240247
</fieldset>
241248

242-
<fieldset><legend>Extra</legend>
249+
<fieldset>
250+
<legend>Extra</legend>
243251
<p>Any additional data you want to add to your profiles goes in here (JSON format).</p>
244-
<textarea name="extra" class="form-control" rows="10" onkeyup="validateJSON(this)">[% $author.extra.json_pretty() %]</textarea><div class="valid">invalid</div>
252+
<textarea name="extra" class="form-control" rows="10">[% $author.extra.json_pretty() %]</textarea>
245253
</fieldset>
246254
<br />
247255
<input type="submit" value="Save Profile" class="btn btn-primary btn-large search-btn" />
248256
</form>
249257
%% }
250258

251-
<script>
252-
253-
function addProfile(select) {
254-
var value = select.value;
255-
var profile = value ? JSON.parse(value) : null;
256-
select.selectedIndex = 0;
257-
var container = $('#metacpan_profiles');
258-
var html = '<div style="display: none" class="form-group'
259-
if (value) {
260-
html += ' profile profile-' + profile.id;
261-
}
262-
html += '"><label class="col-sm-4 col-md-4 control-label">';
263-
if(value) {
264-
html += profile.name
265-
+ '<input type="hidden" name="profile.name" value="' + profile.id + '" /> ';
266-
} else {
267-
html += '<input placeholder="Profile name" class="input-small" type="text" class="form-control" name="profile.name" /> ';
268-
}
269-
html += '</label>'
270-
html += '<div class="col-sm-8 col-md-6"><div class="input-group">'
271-
+ '<input type="text" class="form-control" name="profile.id" /> '
272-
+ '<span class="input-group-btn"><a href="" class="btn btn-danger" class="check" onclick="return removeDiv(this.parentNode.parentNode.parentNode)"><i class="fa fa-trash-alt"></i> remove</a> ';
273-
if (value) {
274-
html += '<a href="" class="btn btn-primary search-btn" tmpl="' + profile.url + '" onclick="return rewriteURL(this)" target="_blank"><i class="fa fa-check-square"></i> check</a>';
275-
}
276-
277-
html += '</span></div></div></div>';
278-
279-
container.append(html);
280-
var add = container.children().last();
281-
add.slideDown();
282-
}
283-
284-
function rewriteURL(link) {
285-
link = $(link);
286-
var url = link.attr('tmpl');
287-
var input = link.parent().prev();
288-
link.attr('href', url.replace('%s', input.val()));
289-
return true;
290-
}
291-
292-
function removeDiv(link) {
293-
$(link).parents('div').first().slideUp("normal", function(){$(this).remove()});
294-
return false;
295-
}
296-
297-
function removeLabel(link) {
298-
$(link).parents('.controls').first().slideUp("normal", function(){$(this).remove()});
299-
return false;
300-
}
301-
302-
function validateJSON(text) {
303-
var valid = $('.valid');
304-
try {
305-
text.value && JSON.parse(text.value);
306-
valid.removeClass('invalid');
307-
} catch(err) {
308-
valid.addClass('invalid');
309-
}
310-
}
311-
312-
function addField(id) {
313-
var input = $('input[name="' + id + '"]').last();
314-
var container = input.parent().parent();
315-
container.append('<div class="input-group"><input type="text" class="form-control" name="' + id + '" /><span class="input-group-btn"><button type="button" class="btn btn-primary search-btn" onclick="return removeDiv(this.parentNode)">remove</button></span></div>');
316-
var add = container.children().last();
317-
add.slideDown();
318-
return false;
319-
}
320-
321-
function fillLocation() {
322-
navigator.geolocation.getCurrentPosition(function(pos) {
323-
$('input[name="latitude"]').val(pos.coords.latitude);
324-
$('input[name="longitude"]').val(pos.coords.longitude);
325-
}, function(){
326-
});
327-
return false;
328-
}
329-
document.addEventListener('DOMContentLoaded', function () {
330-
$(window).bind("resize", formFixer);
331-
formFixer();
332-
});
259+
<template id="profile-tmpl">
260+
<div class="slide-out slide-down profile-container"><div>
261+
<div class="form-group">
262+
<label class="col-sm-4 col-md-4 control-label">
263+
<span class="profile-title"></span>
264+
<input placeholder="Profile name" class="input-small" type="text" class="form-control" name="profile.name" />
265+
</label>
266+
<div class="col-sm-8 col-md-6">
267+
<div class="input-group">
268+
<input type="text" class="form-control" name="profile.id" />
269+
<span class="input-group-btn">
270+
<a href="" class="btn btn-danger remove-profile" class="check"><i class="fa fa-trash-alt"></i> remove</a>
271+
<a href="" class="btn btn-primary search-btn check-url" data-url-template="" target="_blank"><i class="fa fa-check-square"></i> check</a>
272+
</span>
273+
</div>
274+
</div>
275+
</div>
276+
</div></div>
277+
</template>
333278

334-
function formFixer( e ) {
335-
if($(window).width()<=480){
336-
$('form').removeClass('form-horizontal');
337-
}
338-
else{
339-
$('form').addClass('form-horizontal');
340-
}
341-
}
342-
</script>
279+
<template id="field-tmpl">
280+
<div class="slide-out slide-down field-container"><div>
281+
<div class="input-group">
282+
<input type="text" class="form-control" />
283+
<span class="input-group-btn">
284+
<button type="button" class="btn btn-primary search-btn remove-field">remove</button>
285+
</span>
286+
</div>
287+
</div></div>
288+
</template>
343289
</div>
344290
%% }

0 commit comments

Comments
 (0)