PageSourceSearch

https://gpcrdb.org/static/home/js/gpcrdb.js

js gpcrdb.org collected 2026-09-24 09:22:54 UTC 8,659 bytes, 260 lines download raw bytes

1/*eslint complexity: ["error", 15]*/
2/*eslint wrap-iife: ["error", "outside"]*/
3/*eslint quotes: ["error", "double", { "avoidEscape": true }]*/
4
5function select_all(e) {
6  let checkedStatus = $(e).prop("checked");
7
8  $(".select-all  ").each(function() {
9    $(this).prop("checked", checkedStatus);
10  });
11
12  $(".alt").each(function() {
13    $(this).prop("checked", checkedStatus);
14  });
15}
16
17/**
18 * Default Bootstrap alert function that can be used on all GPCRdb pages
19 */
20function showAlert(message, alerttype) {
21  // Alerttype: success, info, warning, danger
22  // See https://getbootstrap.com/docs/3.3/components/#alerts
23  $("#gpcrdb_alert_placeholder").append('<div id="gpcrdb_alert" class="alert alert-' +
24    alerttype + '"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>' +
25    message + "</div>");
26
27  setTimeout(function() {
28    $("#gpcrdb_alert").remove();
29  }, 4000);
30}
31
32/**
33 * This Array filter function can be used to deduplicate an Array
34 */
35function onlyUnique(value, index, self) {
36  return self.indexOf(value) === index;
37}
38
39/**
40 * This function exports a list in a separated fashion to clipboard.
41 */
42function copyListToClipboard(selected, delimiter = " ") {
43  if (selected.length > 0) {
44    // Deduplicate and sort list
45    selected = selected.filter(onlyUnique).sort();
46
47    // Place values in textbox and copy to clipboard
48    var copybox = $('<input type="text">');
49    $(document.body).append(copybox);
50    copybox.val(selected.join(delimiter));
51    copybox.select();
52    copybox[0].setSelectionRange(0, 99999);
53    document.execCommand("copy");
54    showAlert("The selection has been copied to your clipboard.", "info");
55    copybox.remove();
56  } else {
57    showAlert("There is no selection to copy to clipboard.", "warning");
58  }
59}
60
61/**
62 * This helper function can create a range of identical YADCF filters with a single call
63 *
64 * Arg list: createYADCFfilters(start_column, num_cols, filter_type, select_type*, filter_default_label*, filter_reset_button_text*, filter_match_mode*, column_data_type*, width*, html5_data*, ignore_char*, html_data_type*, html5_data*, other*)
65 * Arguments:
66 *   other: a javascript object with column parameters of Yet Another DataTables Column Filter - (yadcf) (jquery.dataTables.yadcf.js)
67 * The asterisk indicates an optional function argument
68 */
69function createYADCFfilters(start_column, num_cols, filter_type, select_type = null, filter_default_label = "", filter_reset_button_text = false, filter_match_mode = null, column_data_type = null, width = null, html5_data = null, ignore_char = null, html_data_type = null, other = null) {
70  
71  let filters = [];
72  for (let i = 0; i < num_cols; i++) {
73    let filter = {
74      "column_number": start_column + i,
75      filter_type,
76      filter_default_label,
77      filter_reset_button_text
78    };
79    if (select_type !== null) {
80      filter["select_type"] = select_type;
81    }
82    if (filter_match_mode !== null) {
83      filter["filter_match_mode"] = filter_match_mode;
84    }
85    if (column_data_type !== null) {
86      filter["column_data_type"] = column_data_type;
87    }
88    if (width !== null) {
89      filter["select_type_options"] = {
90        width
91      };
92    }
93    if (html5_data !== null) {
94      filter["html5_data"] = html5_data;
95    }
96    if (ignore_char !== null) {
97      filter["ignore_char"] = ignore_char;
98    }
99    if (html_data_type !== null) {
100      filter["html_data_type"] = html_data_type;
101    }
102
103    if (other !== null) {
104      $.each( other, function( key, value ) {
105        
106        filter[key] = value;
107      });
108    }
109    filters.push(filter);
110  }
111  
112  return filters;
113}
114
115 
116
117
118/**
119 * Exports a specified table to an Excel file.
120 * @param {string} tableId - The ID of the table element to be exported.
121 * @param {string} sheetName - The name to be given to the Excel sheet.
122 * @param {string} fileName - The name of the file to be created.
123 */
124function GlobalTableToExcel(tableId, sheetName, fileName) {
125  // Get the table element by ID.
126  const tableElement = document.getElementById(tableId);
127
128  // If the table doesn't exist, log an error and exit the function.
129  if (!tableElement) {
130    console.error(`Table with ID "${tableId}" not found.`);
131    return;
132  }
133
134  // Create a new Excel workbook.
135  const wb = XLSX.utils.book_new();
136
137  // Clean the table and prepare it for export.
138  const clonedTable = cleanTable(tableElement.cloneNode(true));
139  const exportTable = prepareExportTable(clonedTable);
140
141  // Convert the prepared table to an Excel worksheet.
142  const ws_data = XLSX.utils.table_to_sheet(exportTable);
143
144  // Add the worksheet to the workbook and write it to a file.
145  XLSX.utils.book_append_sheet(wb, ws_data, sheetName);
146  XLSX.writeFile(wb, fileName, { bookSST: true });
147}
148
149/**
150 * Cleans the table by removing unwanted elements, cleaning headers, and processing cells.
151 * @param {HTMLElement} table - The table to be cleaned.
152 * @return {HTMLElement} The cleaned table.
153 */
154function cleanTable(table) {
155  // Remove unwanted elements, clean headers, and process cells.
156  removeUnwantedElements(table);
157  cleanTableHeaders(table);
158  processTableCells(table);
159
160  // Return the cleaned table.
161  return table;
162}
163
164/**
165 * Removes specific unwanted elements from the table.
166 * @param {HTMLElement} table - The table to be cleaned.
167 */
168function removeUnwantedElements(table) {
169  // Remove elements with class '.yadcf-filter-wrapper' and all buttons.
170  table.querySelectorAll('.yadcf-filter-wrapper').forEach(element => element.closest('tr').remove());
171  table.querySelectorAll('button').forEach(button => button.remove());
172}
173
174/**
175 * Cleans the headers of the table.
176 * @param {HTMLElement} table - The table with headers to be cleaned.
177 */
178function cleanTableHeaders(table) {
179  // Process each header, remove 'span' elements and replace 'br' with space.
180  table.querySelectorAll('th').forEach(th => {
181    const clonedTh = th.cloneNode(true);
182    clonedTh.querySelectorAll('span').forEach(span => span.remove());
183    clonedTh.querySelectorAll('br').forEach(br => br.replaceWith(' '));
184    th.textContent = clonedTh.textContent;
185  });
186}
187
188/**
189 * Processes each cell in the table.
190 * @param {HTMLElement} table - The table with cells to be processed.
191 */
192function processTableCells(table) {
193  // Iterate over each cell to remove comment nodes and process links and line breaks.
194  table.querySelectorAll('td').forEach(td => {
195    Array.from(td.childNodes).forEach(node => {
196      if (node.nodeType === Node.COMMENT_NODE) {
197        node.remove();
198      }
199    });
200    handleImageLinks(td);
201    replaceLineBreaks(td);
202    replaceRefinedLinks(td);
203  });
204}
205
206/**
207 * Converts image links in a table cell to text.
208 * @param {HTMLElement} td - The table cell to process.
209 */
210function handleImageLinks(td) {
211  // If an image within a link is found, replace its content with the link's URL.
212  const img = td.querySelector('img');
213  if (img && img.parentNode.tagName === 'A') {
214    td.textContent = img.parentNode.href;
215  }
216}
217
218/**
219 * Replaces line breaks in a table cell and wraps content in a paragraph tag.
220 * @param {HTMLElement} td - The table cell to process.
221 */
222function replaceLineBreaks(td) {
223  // Get specific HTML content, replace line breaks, and wrap in a paragraph tag.
224  const htmlContent = td.querySelector('a i.glyphicon.glyphicon-file.simple-popover.gpcrdb-link')?.getAttribute('data-content');
225  if (htmlContent) {
226    let newTextContent = htmlContent.replace(/<br>/g, "_X_").replace(/<[^>]*>/g, '').replace(/_X_/g, '<br>' );
227    td.innerHTML = `<p>${newTextContent}</p>`;
228  }
229}
230
231/**
232 * Converts refined links in a table cell to plain text.
233 * @param {HTMLElement} td - The table cell to process.
234 */
235function replaceRefinedLinks(td) {
236  // Replace the text of certain links with their URLs.
237  td.querySelectorAll('a').forEach(a => {
238    if (a.textContent.endsWith('_refined')) {
239      a.textContent = a.href;
240    }
241  });
242}
243
244/**
245 * Prepares the table for export, selecting specific rows or the entire table.
246 * @param {HTMLElement} clonedTable - The cloned table to be prepared for export.
247 * @return {HTMLElement} The table prepared for export.
248 */
249function prepareExportTable(clonedTable) {
250  // Create a new table with selected rows or return the whole table.
251  const selectedRows = clonedTable.querySelectorAll('tr.alt_selected');
252  if (selectedRows.length > 0) {
253    const exportTable = document.createElement('table');
254    exportTable.appendChild(clonedTable.querySelector('thead').cloneNode(true));
255    selectedRows.forEach(row => exportTable.appendChild(row.cloneNode(true)));
256    return exportTable;
257  } else {
258    return clonedTable;
259  }
260}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.