Last active
August 9, 2020 12:12
-
-
Save jraddaoui/85c7b8583af51158e6fabffa773f0890 to your computer and use it in GitHub Desktop.
AtoM clipboard with ES6 classes (no arrow functions and others yet)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($) | |
{ | |
'use strict'; | |
class Clipboard | |
{ | |
constructor(element) | |
{ | |
this.$element = element; | |
this.$menuButton = this.$element.find('> button'); | |
this.$menuHeaderCount = this.$element.find('.top-dropdown-header > span'); | |
this.onClipboardPage = $('body').is('.user.clipboard'); | |
this.storage = localStorage; | |
this.types = ['informationObject', 'actor', 'repository']; | |
this.initialItems = {'informationObject': [], 'actor': [], 'repository': []}; | |
this.items = JSON.parse(this.storage.getItem('clipboard')); | |
this.exportTokens = JSON.parse(this.storage.getItem('exportTokens')); | |
if (!this.items) | |
{ | |
this.items = this.initialItems; | |
} | |
if (!this.exportTokens) | |
{ | |
this.exportTokens = []; | |
} | |
this.init(); | |
} | |
init() | |
{ | |
// Listeners added to the document to affect elements added dynamically | |
$(document).on('click', 'button.clipboard', $.proxy(this.toggle, this, true)); | |
$(document).on('click', 'button.clipboard-wide', $.proxy(this.toggle, this, false)); | |
$(document).on('click', 'button#clipboard-clear, li#node_clearClipboard a', $.proxy(this.clear, this)); | |
$(document).on('click', 'a#clipboard-save, li#node_saveClipboard a', $.proxy(this.save, this)); | |
$(document).on('click', 'button#clipboard-send', $.proxy(this.send, this)); | |
$(document).on('submit', '#clipboard-load-form', $.proxy(this.load, this)); | |
$(document).on('submit', '#clipboard-export-form', $.proxy(this.export, this)); | |
this.updateCounts(); | |
if (this.onClipboardPage) | |
{ | |
this.loadClipboardContent(); | |
} | |
else | |
{ | |
this.updateAllButtons(); | |
} | |
this.checkExports(); | |
} | |
load(event) | |
{ | |
event.preventDefault(); | |
var $form = $(event.target); | |
var mode = $form.find('select#mode').val(); | |
$.ajax({ | |
url: $form.attr('action'), | |
type: 'POST', | |
cache: false, | |
data: $form.serialize(), | |
context: this, | |
success: function(data) | |
{ | |
if (mode === 'merge') | |
{ | |
this.types.map(function(type) | |
{ | |
if (data.clipboard[type]) | |
{ | |
data.clipboard[type].map(function(slug) | |
{ | |
if (this.items[type].indexOf(slug) === -1) | |
{ | |
this.items[type].push(slug); | |
} | |
}, this); | |
} | |
}, this); | |
} | |
else if (mode === 'replace') | |
{ | |
this.items = data.clipboard; | |
} | |
this.storage.setItem('clipboard', JSON.stringify(this.items)); | |
this.updateCounts(); | |
this.showAlert(data.success, 'alert-info'); | |
}, | |
error: function(xhr) | |
{ | |
var data = JSON.parse(xhr.responseText); | |
this.showAlert(data.error, 'alert-error'); | |
} | |
}); | |
} | |
loadClipboardContent() | |
{ | |
var url = new URL(window.location.href); | |
var type = url.searchParams.get('type'); | |
if (!type || !this.types.includes(type)) | |
{ | |
type = 'informationObject'; | |
} | |
// Get clipboard content, use post instead of get to | |
// reduce URL length and simplify cache proxy config. | |
$.ajax({ | |
url: url, | |
type: 'POST', | |
cache: false, | |
data: { slugs: this.items[type] }, | |
context: this, | |
success: function(data) | |
{ | |
// Replace page content | |
$('body > #wrapper').replaceWith($(data).filter('#wrapper')); | |
// Attach expander from qubit.js and other behaviors to new content | |
Drupal.attachBehaviors('#wrapper'); | |
this.updateAllButtons(); | |
}, | |
error: function() | |
{ | |
this.showAlert(this.$element.data('load-alert-message'), 'alert-error'); | |
} | |
}); | |
} | |
save(event) | |
{ | |
event.preventDefault(); | |
// Avoid request if there are no slugs in the clipboard | |
if ( | |
this.items['informationObject'].length === 0 && | |
this.items['actor'].length === 0 && | |
this.items['repository'].length === 0 | |
) | |
{ | |
return; | |
} | |
$.ajax({ | |
url: $(event.target).attr('href'), | |
type: 'POST', | |
cache: false, | |
data: { slugs: this.items }, | |
context: this, | |
success: function(data) | |
{ | |
this.showAlert(data.success, 'alert-info'); | |
}, | |
error: function(xhr) | |
{ | |
var data = JSON.parse(xhr.responseText); | |
this.showAlert(data.error, 'alert-error'); | |
} | |
}); | |
} | |
send(event) | |
{ | |
var $sendButton = $(event.target); | |
// Avoid request if there are no slugs in the clipboard | |
if ( | |
this.items['informationObject'].length === 0 && | |
this.items['actor'].length === 0 && | |
this.items['repository'].length === 0 | |
) | |
{ | |
this.showAlert($sendButton.data('empty-message'), 'alert-error'); | |
return; | |
} | |
// Generate clipboard send data | |
var data = {base_url: $sendButton.data('site-base-url')}; | |
if (this.items['informationObject'].length !== 0) | |
{ | |
data.informationobject_slugs = JSON.stringify(this.items['informationObject']); | |
} | |
if (this.items['actor'].length !== 0) | |
{ | |
data.actor_slugs = JSON.stringify(this.items['actor']); | |
} | |
if (this.items['repository'].length !== 0) | |
{ | |
data.repository_slugs = JSON.stringify(this.items['repository']); | |
} | |
// Show sending alert and assign it to a variable | |
var $sendingAlert = this.showAlert($sendButton.data('message'), 'alert-info'); | |
$.ajax({ | |
url: $sendButton.data('url'), | |
type: $sendButton.data('method'), | |
cache: false, | |
data: data, | |
context: this, | |
complete: function() | |
{ | |
// Remove alert on error and success | |
$sendingAlert.remove(); | |
} | |
}); | |
} | |
export(event) | |
{ | |
event.preventDefault(); | |
var $form = $(event.target); | |
var type = $form.find('select#type').val(); | |
// Avoid request if there are no slugs for the type | |
if (this.items[type].length === 0) | |
{ | |
this.showAlert(this.$element.data('export-alert-message'), 'alert-error'); | |
return; | |
} | |
// Merge form data and slugs | |
var data = $form.serializeArray(); | |
this.items[type].map(function(slug) | |
{ | |
data.push({name: 'slugs[]', value: slug}); | |
}); | |
$.ajax({ | |
url: $form.attr('action'), | |
type: 'POST', | |
cache: false, | |
data: data, | |
context: this, | |
success: function(responseData) | |
{ | |
this.showAlert(responseData.success, 'alert-info'); | |
// Unauthenticated users will get a token to check the export | |
if (responseData.token) | |
{ | |
this.exportTokens.push(responseData.token); | |
this.storage.setItem('exportTokens', JSON.stringify(this.exportTokens)); | |
} | |
}, | |
error: function(xhr) | |
{ | |
var data = JSON.parse(xhr.responseText); | |
this.showAlert(data.error, 'alert-error'); | |
} | |
}); | |
} | |
checkExports() | |
{ | |
if (this.exportTokens.length === 0) | |
{ | |
return; | |
} | |
// Use post instead of get to send the tokens | |
// in the body and simplify cache proxy config. | |
$.ajax({ | |
url: this.$element.data('export-check-url'), | |
type: 'POST', | |
cache: false, | |
data: { tokens: this.exportTokens }, | |
context: this, | |
success: function(data) | |
{ | |
// Show status alerts | |
if (data.alerts) | |
{ | |
data.alerts.map(function(alert) | |
{ | |
this.showAlert(alert.message, 'alert-' + alert.type, alert.deleteUrl); | |
}, this); | |
} | |
// Clear missing tokens | |
if (data.missingTokens) | |
{ | |
data.missingTokens.map(function(token) | |
{ | |
var index = this.exportTokens.indexOf(token); | |
if (index !== -1) | |
{ | |
this.exportTokens.splice(index, 1); | |
} | |
}, this); | |
this.storage.setItem('exportTokens', JSON.stringify(this.exportTokens)); | |
} | |
}, | |
error: function(xhr) | |
{ | |
var data = JSON.parse(xhr.responseText); | |
this.showAlert(data.error, 'alert-error'); | |
} | |
}); | |
} | |
toggle(reloadTooltip, event) | |
{ | |
if (typeof event.preventDefault === 'function') | |
{ | |
event.preventDefault(); | |
} | |
var $button = $(event.target); | |
if (reloadTooltip) | |
{ | |
$button.tooltip('hide'); | |
} | |
var type = $button.data('clipboard-type'); | |
var slug = $button.data('clipboard-slug'); | |
var index = this.items[type].indexOf(slug); | |
if (index === -1) | |
{ | |
this.items[type].push(slug); | |
this.updateButton($button, true, reloadTooltip); | |
} | |
else | |
{ | |
this.items[type].splice(index, 1); | |
this.updateButton($button, false, reloadTooltip); | |
} | |
this.storage.setItem('clipboard', JSON.stringify(this.items)); | |
this.updateCounts(); | |
} | |
clear(event) | |
{ | |
event.preventDefault(); | |
this.showRemoveAlert(); | |
var $target = $(event.target); | |
var type = $target.data('clipboard-type'); | |
if (type && this.types.includes(type)) | |
{ | |
this.items[type] = []; | |
} | |
else | |
{ | |
this.items = this.initialItems; | |
} | |
this.storage.setItem('clipboard', JSON.stringify(this.items)); | |
this.updateCounts(); | |
this.updateAllButtons(); | |
} | |
updateButton($button, added, reloadTooltip) | |
{ | |
// If previous and current status don't match, | |
// change status, tooltip and button content | |
if ((!$button.hasClass('added') && added) | |
|| ($button.hasClass('added') && !added)) | |
{ | |
// Show alert when removing | |
if (!added) | |
{ | |
this.showRemoveAlert(); | |
} | |
$button.toggleClass('added'); | |
var label = $button.attr('data-title'); | |
var altLabel = $button.attr('data-alt-title'); | |
$button.attr('data-alt-title', label); | |
$button.attr('data-title', altLabel); | |
$button.text(altLabel); | |
// Fix tooltip only in small buttons | |
if (reloadTooltip) | |
{ | |
$button.tooltip() | |
.attr('data-original-title', altLabel) | |
.tooltip('fixTitle'); | |
} | |
} | |
} | |
updateCounts() | |
{ | |
var iosCount = this.items['informationObject'].length; | |
var actorsCount = this.items['actor'].length; | |
var reposCount = this.items['repository'].length; | |
var totalCount = iosCount + actorsCount + reposCount; | |
// Menu button count | |
var $buttonSpan = this.$menuButton.find('> span'); | |
if (!$buttonSpan.length && totalCount > 0) | |
{ | |
this.$menuButton.append('<span>' + totalCount + '</span>'); | |
} | |
else if (totalCount > 0) | |
{ | |
$buttonSpan.text(totalCount); | |
} | |
else if ($buttonSpan.length) | |
{ | |
$buttonSpan.remove(); | |
} | |
// Menu dropdown header count | |
var countText = this.$menuHeaderCount.data('information-object-label'); | |
countText += ' count: ' + iosCount + '<br />'; | |
countText += this.$menuHeaderCount.data('actor-object-label'); | |
countText += ' count: ' + actorsCount + '<br />'; | |
countText += this.$menuHeaderCount.data('repository-object-label'); | |
countText += ' count: ' + reposCount + '<br />'; | |
this.$menuHeaderCount.html(countText); | |
} | |
updateAllButtons() | |
{ | |
$('button.clipboard').tooltip({'placement': 'bottom', 'container': 'body'}); | |
var self = this; | |
$('button[class*="clipboard"]').each(function() | |
{ | |
var $button = $(this); | |
var type = $button.data('clipboard-type'); | |
var slug = $button.data('clipboard-slug'); | |
var reloadTooltip = $button.hasClass('clipboard'); | |
var added = self.items[type].indexOf(slug) !== -1; | |
self.updateButton($button, added, reloadTooltip); | |
}); | |
} | |
showAlert(message, type, deleteUrl) | |
{ | |
if (!type) | |
{ | |
type = ''; | |
} | |
var $alert = $('<div class="alert ' + type + '">'); | |
if (deleteUrl) | |
{ | |
$alert.append('<a href="' + deleteUrl + '"><button type="button" class="close">×</button></a>'); | |
} | |
else | |
{ | |
$alert.append('<button type="button" data-dismiss="alert" class="close">×</button>'); | |
} | |
$alert.append(message).prependTo($('#wrapper.container')); | |
return $alert; | |
} | |
showRemoveAlert() | |
{ | |
// Show remove alert only in clipboard page if it is not already added | |
if (this.onClipboardPage && $('#wrapper.container > .alert-clipboard-remove').length == 0) | |
{ | |
this.showAlert(this.$element.data('delete-alert-message'), 'alert-clipboard-remove'); | |
} | |
} | |
}; | |
$(function() | |
{ | |
var $clipboard = $('#clipboard-menu'); | |
if ($clipboard.length) | |
{ | |
$clipboard.data('clipboard', new Clipboard($clipboard)); | |
} | |
}); | |
})(jQuery); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/js/clipboard.js b/js/clipboard.js | |
index 892cc6a69..32190c2fd 100644 | |
--- a/js/clipboard.js | |
+++ b/js/clipboard.js | |
@@ -2,35 +2,35 @@ | |
{ | |
'use strict'; | |
- function Clipboard(element) | |
+ class Clipboard | |
{ | |
- this.$element = element; | |
- this.$menuButton = this.$element.find('> button'); | |
- this.$menuHeaderCount = this.$element.find('.top-dropdown-header > span'); | |
- this.onClipboardPage = $('body').is('.user.clipboard'); | |
- | |
- this.storage = localStorage; | |
- this.types = ['informationObject', 'actor', 'repository']; | |
- this.initialItems = {'informationObject': [], 'actor': [], 'repository': []}; | |
- this.items = JSON.parse(this.storage.getItem('clipboard')); | |
- this.exportTokens = JSON.parse(this.storage.getItem('exportTokens')); | |
- | |
- if (!this.items) | |
+ constructor(element) | |
{ | |
- this.items = this.initialItems; | |
- } | |
- | |
- if (!this.exportTokens) | |
- { | |
- this.exportTokens = []; | |
- } | |
+ this.$element = element; | |
+ this.$menuButton = this.$element.find('> button'); | |
+ this.$menuHeaderCount = this.$element.find('.top-dropdown-header > span'); | |
+ this.onClipboardPage = $('body').is('.user.clipboard'); | |
+ | |
+ this.storage = localStorage; | |
+ this.types = ['informationObject', 'actor', 'repository']; | |
+ this.initialItems = {'informationObject': [], 'actor': [], 'repository': []}; | |
+ this.items = JSON.parse(this.storage.getItem('clipboard')); | |
+ this.exportTokens = JSON.parse(this.storage.getItem('exportTokens')); | |
+ | |
+ if (!this.items) | |
+ { | |
+ this.items = this.initialItems; | |
+ } | |
- this.init(); | |
- }; | |
+ if (!this.exportTokens) | |
+ { | |
+ this.exportTokens = []; | |
+ } | |
- Clipboard.prototype = { | |
+ this.init(); | |
+ } | |
- init: function() | |
+ init() | |
{ | |
// Listeners added to the document to affect elements added dynamically | |
$(document).on('click', 'button.clipboard', $.proxy(this.toggle, this, true)); | |
@@ -53,8 +53,9 @@ | |
} | |
this.checkExports(); | |
- }, | |
- load: function(event) | |
+ } | |
+ | |
+ load(event) | |
{ | |
event.preventDefault(); | |
@@ -100,8 +101,9 @@ | |
this.showAlert(data.error, 'alert-error'); | |
} | |
}); | |
- }, | |
- loadClipboardContent: function() | |
+ } | |
+ | |
+ loadClipboardContent() | |
{ | |
var url = new URL(window.location.href); | |
var type = url.searchParams.get('type'); | |
@@ -134,8 +136,9 @@ | |
this.showAlert(this.$element.data('load-alert-message'), 'alert-error'); | |
} | |
}); | |
- }, | |
- save: function(event) | |
+ } | |
+ | |
+ save(event) | |
{ | |
event.preventDefault(); | |
@@ -165,8 +168,9 @@ | |
this.showAlert(data.error, 'alert-error'); | |
} | |
}); | |
- }, | |
- send: function(event) | |
+ } | |
+ | |
+ send(event) | |
{ | |
var $sendButton = $(event.target); | |
@@ -215,8 +219,9 @@ | |
$sendingAlert.remove(); | |
} | |
}); | |
- }, | |
- export: function(event) | |
+ } | |
+ | |
+ export(event) | |
{ | |
event.preventDefault(); | |
@@ -261,8 +266,9 @@ | |
this.showAlert(data.error, 'alert-error'); | |
} | |
}); | |
- }, | |
- checkExports: function() | |
+ } | |
+ | |
+ checkExports() | |
{ | |
if (this.exportTokens.length === 0) | |
{ | |
@@ -310,8 +316,9 @@ | |
this.showAlert(data.error, 'alert-error'); | |
} | |
}); | |
- }, | |
- toggle: function(reloadTooltip, event) | |
+ } | |
+ | |
+ toggle(reloadTooltip, event) | |
{ | |
if (typeof event.preventDefault === 'function') | |
{ | |
@@ -342,8 +349,9 @@ | |
this.storage.setItem('clipboard', JSON.stringify(this.items)); | |
this.updateCounts(); | |
- }, | |
- clear: function(event) | |
+ } | |
+ | |
+ clear(event) | |
{ | |
event.preventDefault(); | |
@@ -365,8 +373,9 @@ | |
this.updateCounts(); | |
this.updateAllButtons(); | |
- }, | |
- updateButton: function($button, added, reloadTooltip) | |
+ } | |
+ | |
+ updateButton($button, added, reloadTooltip) | |
{ | |
// If previous and current status don't match, | |
// change status, tooltip and button content | |
@@ -396,8 +405,9 @@ | |
.tooltip('fixTitle'); | |
} | |
} | |
- }, | |
- updateCounts: function() | |
+ } | |
+ | |
+ updateCounts() | |
{ | |
var iosCount = this.items['informationObject'].length; | |
var actorsCount = this.items['actor'].length; | |
@@ -428,8 +438,9 @@ | |
countText += ' count: ' + reposCount + '<br />'; | |
this.$menuHeaderCount.html(countText); | |
- }, | |
- updateAllButtons: function() | |
+ } | |
+ | |
+ updateAllButtons() | |
{ | |
$('button.clipboard').tooltip({'placement': 'bottom', 'container': 'body'}); | |
@@ -445,8 +456,9 @@ | |
self.updateButton($button, added, reloadTooltip); | |
}); | |
- }, | |
- showAlert: function(message, type, deleteUrl) | |
+ } | |
+ | |
+ showAlert(message, type, deleteUrl) | |
{ | |
if (!type) | |
{ | |
@@ -467,8 +479,9 @@ | |
$alert.append(message).prependTo($('#wrapper.container')); | |
return $alert; | |
- }, | |
- showRemoveAlert: function() | |
+ } | |
+ | |
+ showRemoveAlert() | |
{ | |
// Show remove alert only in clipboard page if it is not already added | |
if (this.onClipboardPage && $('#wrapper.container > .alert-clipboard-remove').length == 0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment