Give a smaller viewport to webkit.org on devices
[WebKit-https.git] / Websites / webkit.org / team.html
1 <?php 
2 $title = "WebKit Team";
3 include("header.inc");
4 ?>
5
6 <h2>WebKit Team</h2>
7
8 <p>Here is the key for each item:</p>
9 <ul>
10     <li><strong class="name">Name</strong> <span class="nick">(IRC nickname)</span> <em class="affiliation">Affiliation</em>
11         <ul><li class="expertise">Areas of knowledge</li></ul>
12     </li>
13 </ul>
14
15 <div id="container">
16 <h2>Reviewers</h2>
17 <ul id="reviewers"></ul>
18
19 <h2>Committers</h2>
20 <ul id="committers"></ul>
21
22 <h2>Contributors</h2>
23 <ul id="contributors"></ul>
24 </div>
25
26 <script>
27
28 var svnTrunkUrl = 'http://svn.webkit.org/repository/webkit/trunk/';
29 var domainAffiliations = {
30     'apple.com': 'Apple',
31     'adobe.com': 'Adobe',
32     'basyskom.com': 'basysKom GmbH',
33     'collabora.co.uk': 'Collabora',
34     'company100.com': 'Company100',
35     'google.com': 'Google',
36     'igalia.com': 'Igalia',
37     'intel.com' : 'Intel',
38     'motorola.com': 'Motorola Mobility',
39     'nokia.com': 'Nokia',
40     'openbossa.org': 'INdT / Nokia',
41     'profusion.mobi': 'ProFUSION',
42     'rim.com': 'Research In Motion',
43     'samsung.com': 'Samsung Electronics',
44     'sencha.com': 'Sencha',
45     'sisa.samsung.com': 'Samsung Electronics',
46     'torchmobile.com.cn': 'Torch Mobile (Beijing) Co. Ltd.',
47     'digia.com': 'Digia',
48     'partner.samsung.com': 'Samsung Electronics',
49
50     // Universities
51     'inf.u-szeged.hu': 'University of Szeged',
52
53     // Open source communities
54     'chromium.org': 'Chromium',
55     'codeaurora.org': 'Code Aurora Forum',
56     'gnome.org': 'GNOME',
57     'kde.org': 'KDE'
58 };
59
60 function parseContributorsJSON(text) {
61     var contributorsJSON = JSON.parse(text);
62     var contributors = [];
63
64     for (var contributorType in contributorsJSON) {
65         for (var contributor in contributorsJSON[contributorType]) {
66             contributors.push({
67                 name: contributor,
68                 kind: contributorType.replace(/s$/, "").toLowerCase(),
69                 emails: contributorsJSON[contributorType][contributor].emails,
70                 nicks: contributorsJSON[contributorType][contributor].nicks,
71                 expertise: contributorsJSON[contributorType][contributor].expertise
72             });
73         }
74     }
75     return contributors;
76 }
77
78 function formatAffiliation(contributor) {
79     if (contributor.affiliation)
80         return contributor.affiliation;
81
82     if (!contributor.emails || !contributor.emails.length)
83         return null;
84
85     var affiliations = [];
86     for (var domain in domainAffiliations) {
87         for (var i = 0; i < contributor.emails.length; i++) {
88             if (contributor.emails[i].indexOf('@' + domain) > 0 && affiliations.indexOf(domainAffiliations[domain]) < 0)
89                 affiliations.push(domainAffiliations[domain]);
90         }
91     }
92     return affiliations.join(' / ');
93 }
94
95 function addText(container, text) { container.appendChild(document.createTextNode(text)); }
96
97 function addWrappedText(container, tagName, attributes, text) {
98     var element = document.createElement(tagName);
99     for (var name in attributes)
100         element.setAttribute(name, attributes[name]);
101     addText(element, text);
102     container.appendChild(element);
103 }
104
105 function populateContributorListItem(listItem, contributor) {
106     addWrappedText(listItem, 'strong', {'class': 'name'}, contributor.name);
107     if (contributor.nicks) {
108         addText(listItem, ' (');
109         addWrappedText(listItem, 'span', {'class': 'nicks'}, contributor.nicks.join(', '));
110         addText(listItem, ')');
111     }
112
113     var affiliation = formatAffiliation(contributor);
114     if (affiliation) {
115         addText(listItem, ' ');
116         addWrappedText(listItem, 'em', {'class': 'affiliation'}, affiliation);        
117     }
118
119     if (contributor.expertise) {
120         var expertiseList = document.createElement('ul');
121         addWrappedText(expertiseList, 'li', {'class': 'expertise'}, contributor.expertise);
122         listItem.appendChild(expertiseList);
123     }
124 }
125
126 function populateContributorList(contributors, kind) {
127     var contributorsOfKind = contributors.filter(function(contributor) { return contributor.kind == kind; });
128     var listElement = document.getElementById(kind + 's');
129     for (var i = 0; i < contributorsOfKind.length; i++) {
130         var listItem = document.createElement('li');
131         listElement.appendChild(listItem);
132         populateContributorListItem(listItem, contributorsOfKind[i]);
133     }
134 }
135
136 function nicksInListItem(listItem) {
137     var nicksContainer = listItem.querySelector('.nicks');
138     if (!nicksContainer || !nicksContainer.textContent)
139         return null;
140     return nicksContainer.textContent.split(/,\s*/);
141 }
142
143 function findListChildForContributor(contributor) {
144     var listChildren = document.getElementsByTagName('li');
145     for (var i = 0; i < listChildren.length; i++) {
146         var nameContainer = listChildren[i].querySelector('.name');
147         if (nameContainer && nameContainer.textContent.toLowerCase().indexOf(contributor.name.toLowerCase()) >= 0)
148             return listChildren[i];
149         var nicksInContainer = nicksInListItem(listChildren[i]);
150         if (nicksInContainer && contributor.nicks) {
151             for (var j = 0; j < contributor.nicks.length; j++) {
152                 if (nicksInContainer.indexOf(contributor.nicks[j]) >= 0)
153                     return listChildren[i];
154             }
155         }
156     }
157     return null;
158 }
159
160 function annotateWithWikiData() {
161     function annotateForContributor(contributor) {
162         var listItem = findListChildForContributor(contributor);
163         if (!listItem) {
164             var listElement = document.getElementById(contributor.kind + 's');
165             var listItem = document.createElement('li');
166             listElement.appendChild(listItem);
167             listItem.style.backgroundColor = 'red';
168             populateContributorListItem(listItem, contributor);
169         } else {
170             var affiliationContainer = listItem.querySelector('.affiliation');
171             var affiliation = formatAffiliation(contributor);
172             if (affiliation && (!affiliationContainer || affiliationContainer.textContent != affiliation)) {
173                 addText(listItem, ' ');
174                 addWrappedText(listItem, 'em', {'style': 'background-color:red'}, affiliation);
175             }
176         }
177     }
178
179     var webkitTeamWikiUrl = 'http://trac.webkit.org/wiki/WebKit%20Team';
180     var xhr = new XMLHttpRequest();
181     xhr.onload = function () {
182         if (this.status !== 200)
183             return this.onerror();
184
185         var lines = this.responseText.split('\n');
186         // Match lines like * '''Ryosuke Niwa''' (rniwa) ''Google''
187         var teamWikiContributorEntryPattern = /^\s+\*\s+'''([^']+)'''\s*(\(([^']+)\)\s*)?(''([^']+)'')?\s*$/;
188         for (var i = 0; i < lines.length; i++) {
189             var match = lines[i].match(/\=\s+(Reviewer|Committer|Contributor)s\s+=/i);
190             if (match) {
191                 var currentKind = match[1].toLowerCase();
192                 continue;
193             }
194
195             // Strip special HTML characters
196             match = lines[i].replace(/[{}<>"%;&+/]/g, '').match(teamWikiContributorEntryPattern);
197             if (currentKind && match) {
198                 annotateForContributor({
199                     kind: currentKind,
200                     name: match[1],
201                     nicks: match[3] ? match[3].split(/,\s*/) : null,
202                     affiliation: match[5]
203                 });
204             }
205         }
206     }
207     xhr.onerror = function () { alert('Could not obtain http://trac.webkit.org/wiki/WebKit%20Team'); };
208     xhr.open('GET', webkitTeamWikiUrl + '?format=txt');
209     xhr.send();
210 }
211
212 var xhr = new XMLHttpRequest();
213 xhr.onload = function () {
214     if (this.status !== 200)
215         return this.onerror();
216     var contributors = parseContributorsJSON(this.responseText);
217
218     populateContributorList(contributors, 'reviewer');
219     populateContributorList(contributors, 'committer');
220     populateContributorList(contributors, 'contributor');
221
222     if (location.search.indexOf('annotate') >= 0)
223         annotateWithWikiData();
224 };
225 xhr.onerror = function () { document.getElementById('container').textContent = 'Could not obtain contributors.json'; };
226 xhr.open('GET', svnTrunkUrl + 'Tools/Scripts/webkitpy/common/config/contributors.json');
227 xhr.send();
228
229 </script>
230
231 <?php
232 include("footer.inc");
233 ?>