From 7d3a67a92905264e4c1691b90d13a34523cfe8b0 Mon Sep 17 00:00:00 2001 From: Huda Khan Date: Fri, 6 Dec 2024 09:46:12 -0700 Subject: [PATCH 01/22] first pass --- .../javascripts/spotlight/spotlight.esm.js | 91 ++++++++++++++++--- .../spotlight/spotlight.esm.js.map | 2 +- app/assets/javascripts/spotlight/spotlight.js | 91 ++++++++++++++++--- .../javascripts/spotlight/spotlight.js.map | 2 +- .../spotlight/select_image_component.html.erb | 35 +++++++ .../spotlight/select_image_component.rb | 26 ++++++ .../spotlight/catalog_controller.rb | 7 ++ .../spotlight/admin/blocks/resources_block.js | 72 ++++++++++++++- .../admin/blocks/solr_documents_base_block.js | 2 +- .../blocks/solr_documents_embed_block.js | 1 + app/javascript/spotlight/admin/croppable.js | 6 +- .../spotlight/catalog/select_image.html.erb | 1 + config/routes.rb | 2 + 13 files changed, 308 insertions(+), 30 deletions(-) create mode 100644 app/components/spotlight/select_image_component.html.erb create mode 100644 app/components/spotlight/select_image_component.rb create mode 100644 app/views/spotlight/catalog/select_image.html.erb diff --git a/app/assets/javascripts/spotlight/spotlight.esm.js b/app/assets/javascripts/spotlight/spotlight.esm.js index f0c5a3ace..9b4b329ac 100644 --- a/app/assets/javascripts/spotlight/spotlight.esm.js +++ b/app/assets/javascripts/spotlight/spotlight.esm.js @@ -3981,6 +3981,10 @@ class Crop { class Croppable { connect() { + this.initializeExistingCropper(); + } + + initializeExistingCropper() { $('[data-behavior="iiif-cropper"]').each(function() { var cropElement = $(this); new Crop(cropElement).render(); @@ -4603,6 +4607,7 @@ class Pages { var editor = new SirTrevor.Editor({ el: instance[0], blockTypes: instance.data('blockTypes'), + altTextSettings: instance.data('altTextSettings'), defaultType:["Text"], onEditorRender: function() { $.SerializedForm(); @@ -5452,18 +5457,17 @@ Spotlight$1.Block.Resources = (function(){ formable: true, autocompleteable: true, show_heading: true, - show_alt_text: true, - + show_image_selection: true, title: function() { return i18n.t("blocks:" + this.type + ":title"); }, description: function() { return i18n.t("blocks:" + this.type + ":description"); }, - alt_text_guidelines: function() { - if (this.show_alt_text) { + alt_text_guidelines: function() { + if (this.showAltText()) { return i18n.t("blocks:alt_text_guidelines:intro"); } return ""; }, alt_text_guidelines_link: function() { - if (this.show_alt_text) { + if (this.showAltText()) { var link_url = i18n.t("blocks:alt_text_guidelines:link_url"); var link_label = i18n.t("blocks:alt_text_guidelines:link_label"); return '' + link_label + ''; @@ -5489,12 +5493,29 @@ Spotlight$1.Block.Resources = (function(){ }, _altTextFieldsHTML: function(index, data) { - if (this.show_alt_text) { + if (this.showAltText()) { return this.altTextHTML(index, data); } return ""; }, + showAltText: function() { + return this.editorOptions.altTextSettings[this._typeAsCamelCase()] + }, + + _typeAsCamelCase: function() { + return this.type + .split('_') + .map(word => word.charAt(0).toUpperCase() + word.slice(1)) + .join(''); + }, + _itemSelectImageLink: function(data) { + var markup = ` +
+ Select image +
`; + return markup; + }, _itemPanel: function(data) { var index = "item_" + this.globalIndex++; var checked; @@ -5521,7 +5542,8 @@ Spotlight$1.Block.Resources = (function(){
-
+ ${this._itemSelectImageLink(data)} +
${data.title}
${(data.slug || data.id)}
@@ -5553,7 +5575,7 @@ Spotlight$1.Block.Resources = (function(){ }, afterPanelRender: function(data, panel) { - + }, afterPanelDelete: function() { @@ -5561,6 +5583,8 @@ Spotlight$1.Block.Resources = (function(){ }, createItemPanel: function(data) { + console.log("Create Item Panel"); + console.log(data); var panel = this._itemPanel(data); this.attachAltTextHandlers(panel); $(panel).appendTo($('.panels > ol', this.inner)); @@ -5632,7 +5656,7 @@ Spotlight$1.Block.Resources = (function(){ }, attachAltTextHandlers: function(panel) { - if (this.show_alt_text) { + if (this.showAltText()) { const decorativeCheckbox = $('input[name$="[decorative]"]', panel); const altTextInput = $('textarea[name$="[alt_text]"]', panel); const altTextBackupInput = $('input[name$="[alt_text_backup]"]', panel); @@ -5667,7 +5691,52 @@ Spotlight$1.Block.Resources = (function(){ $.each(Object.keys(data.item || {}).map(function(k) { return data.item[k]}).sort(function(a,b) { return a.weight - b.weight; }), function(index, item) { context.createItemPanel(item); }); + // For resource blocks that allow for selection of region for images for items + if(this.show_image_selection) { + this.attachModalHandler(); + } + }, + + attachModalHandler: function() { + var context = this; + document.addEventListener('show.blacklight.blacklight-modal', function(e) { + context.setCropperFields(); + var c = new Croppable(); + c.initializeExistingCropper(); + }); + }, + + setCropperFields: function() { + var dataCropperDiv = $('#blacklight-modal [data-cropper]'); + var prefix = dataCropperDiv.data('form-prefix'); + var idField = $('#' + prefix + '_id'); + var id = idField.val(); + // The elements in the blacklight modal + var iiifUrlField = $('#' + prefix + '_iiif_tilesource'); + var iiifRegionField = $('#' + prefix + '_iiif_region'); + var iiifManifestField = $('#' + prefix + '_iiif_manifest_url'); + var iiifCanvasField = $('#' + prefix + '_iiif_canvas_id'); + var iiifImageField = $('#' + prefix + '_iiif_image_id'); + + //With the ID, get the hidden inputs related to this particular element in the form + var itemPanelInfo = $("li[data-resource-id='" + id + "']"); + var dataId = itemPanelInfo.data('id'); + var itemPrefix = "input[name='item[" + dataId + "]"; + // Get values from the item panel which already includes the IIIF values needed + var url = $(itemPrefix + "[iiif_tilesource]'").val(); + var region = $(itemPrefix + "[iiif_region]'").val(); + var manifest = $(itemPrefix + "[iiif_manifest_url]'").val(); + var canvas = $(itemPrefix + "[iiif_canvas_id]'").val(); + var image = $(itemPrefix + "[iiif_image_id]'").val(); + + // Set the values in the blacklight modal window + iiifUrlField.val(url); + iiifRegionField.val(region); + iiifManifestField.val(manifest); + iiifCanvasField.val(canvas); + iiifImageField.val(image); + } }); })(); @@ -6101,7 +6170,7 @@ SirTrevor.Blocks.SolrDocumentsBase = (function(){ $(panel).find('[name$="[iiif_canvas_id]"]').val(manifest_data.canvasId); $(panel).find('img.img-thumbnail').attr('src', manifest_data.thumbnail_image_url || manifest_data.tilesource.replace("/info.json", "/full/100,100/0/default.jpg")); }, - afterPanelRender: function(data, panel) { + afterPanelRender: function(data, panel) { var context = this; var manifestUrl = data.iiif_manifest || data.iiif_manifest_url; @@ -6268,8 +6337,8 @@ SirTrevor.Blocks.SolrDocumentsEmbed = (function(){ return SirTrevor.Blocks.SolrDocumentsBase.extend({ type: "solr_documents_embed", - show_alt_text: false, icon_name: "item_embed", + show_image_selection: false, item_options: function() { return "" }, diff --git a/app/assets/javascripts/spotlight/spotlight.esm.js.map b/app/assets/javascripts/spotlight/spotlight.esm.js.map index 29f47e338..2506045fb 100644 --- a/app/assets/javascripts/spotlight/spotlight.esm.js.map +++ b/app/assets/javascripts/spotlight/spotlight.esm.js.map @@ -1 +1 @@ -{"version":3,"file":"spotlight.esm.js","sources":["../../../../vendor/assets/javascripts/tiny-slider.js","../../../javascript/spotlight/user/browse_group_categories.js","../../../javascript/spotlight/user/carousel.js","../../../javascript/spotlight/user/clear_form_button.js","../../../javascript/spotlight/user/report_a_problem.js","../../../javascript/spotlight/user/zpr_links.js","../../../javascript/spotlight/user/index.js","../../../javascript/spotlight/admin/add_another.js","../../../javascript/spotlight/admin/add_new_button.js","../../../javascript/spotlight/admin/blacklight_configuration.js","../../../javascript/spotlight/admin/copy_email_addresses.js","../../../javascript/spotlight/admin/iiif.js","../../../javascript/spotlight/admin/add_image_selector.js","../../../javascript/spotlight/core.js","../../../javascript/spotlight/admin/crop.js","../../../javascript/spotlight/admin/croppable.js","../../../javascript/spotlight/admin/edit_in_place.js","../../../javascript/spotlight/admin/exhibit_tag_autocomplete.js","../../../../vendor/assets/javascripts/parameterize.js","../../../javascript/spotlight/admin/exhibits.js","../../../javascript/spotlight/admin/form_observer.js","../../../javascript/spotlight/admin/locks.js","../../../javascript/spotlight/admin/multi_image_selector.js","../../../javascript/spotlight/admin/pages.js","../../../javascript/spotlight/admin/progress_monitor.js","../../../javascript/spotlight/admin/readonly_checkbox.js","../../../javascript/spotlight/admin/search_typeahead.js","../../../javascript/spotlight/admin/select_related_input.js","../../../javascript/spotlight/admin/spotlight_nestable.js","../../../javascript/spotlight/admin/tabs.js","../../../javascript/spotlight/admin/translation_progress.js","../../../javascript/spotlight/admin/visibility_toggle.js","../../../javascript/spotlight/admin/users.js","../../../javascript/spotlight/admin/block_mixins/autocompleteable.js","../../../javascript/spotlight/admin/block_mixins/formable.js","../../../javascript/spotlight/admin/block_mixins/plustextable.js","../../../javascript/spotlight/admin/blocks/block.js","../../../javascript/spotlight/admin/blocks/resources_block.js","../../../javascript/spotlight/admin/blocks/browse_block.js","../../../javascript/spotlight/admin/blocks/browse_group_categories_block.js","../../../javascript/spotlight/admin/blocks/iframe_block.js","../../../javascript/spotlight/admin/blocks/link_to_search_block.js","../../../javascript/spotlight/admin/blocks/oembed_block.js","../../../javascript/spotlight/admin/blocks/pages_block.js","../../../javascript/spotlight/admin/blocks/rule_block.js","../../../javascript/spotlight/admin/blocks/search_result_block.js","../../../javascript/spotlight/admin/blocks/solr_documents_base_block.js","../../../javascript/spotlight/admin/blocks/solr_documents_block.js","../../../javascript/spotlight/admin/blocks/solr_documents_carousel_block.js","../../../javascript/spotlight/admin/blocks/solr_documents_embed_block.js","../../../javascript/spotlight/admin/blocks/solr_documents_features_block.js","../../../javascript/spotlight/admin/blocks/solr_documents_grid_block.js","../../../javascript/spotlight/admin/blocks/uploaded_items_block.js","../../../javascript/spotlight/admin/sir-trevor/block_controls.js","../../../javascript/spotlight/admin/sir-trevor/block_limits.js","../../../javascript/spotlight/admin/sir-trevor/locales.js","../../../javascript/spotlight/admin/index.js","../../../javascript/spotlight/index.js"],"sourcesContent":["// Includes an unreleased RTL support pull request: https://github.com/ganlanyuan/tiny-slider/pull/658\n// Includes \"export default tns\" at the end of the file for spotlight/user/browse_group_categories.js\nvar tns = (function (){\nvar win = window;\n\nvar raf = win.requestAnimationFrame\n || win.webkitRequestAnimationFrame\n || win.mozRequestAnimationFrame\n || win.msRequestAnimationFrame\n || function(cb) { return setTimeout(cb, 16); };\n\nvar win$1 = window;\n\nvar caf = win$1.cancelAnimationFrame\n || win$1.mozCancelAnimationFrame\n || function(id){ clearTimeout(id); };\n\nfunction extend() {\n var obj, name, copy,\n target = arguments[0] || {},\n i = 1,\n length = arguments.length;\n\n for (; i < length; i++) {\n if ((obj = arguments[i]) !== null) {\n for (name in obj) {\n copy = obj[name];\n\n if (target === copy) {\n continue;\n } else if (copy !== undefined) {\n target[name] = copy;\n }\n }\n }\n }\n return target;\n}\n\nfunction checkStorageValue (value) {\n return ['true', 'false'].indexOf(value) >= 0 ? JSON.parse(value) : value;\n}\n\nfunction setLocalStorage(storage, key, value, access) {\n if (access) {\n try { storage.setItem(key, value); } catch (e) {}\n }\n return value;\n}\n\nfunction getSlideId() {\n var id = window.tnsId;\n window.tnsId = !id ? 1 : id + 1;\n \n return 'tns' + window.tnsId;\n}\n\nfunction getBody () {\n var doc = document,\n body = doc.body;\n\n if (!body) {\n body = doc.createElement('body');\n body.fake = true;\n }\n\n return body;\n}\n\nvar docElement = document.documentElement;\n\nfunction setFakeBody (body) {\n var docOverflow = '';\n if (body.fake) {\n docOverflow = docElement.style.overflow;\n //avoid crashing IE8, if background image is used\n body.style.background = '';\n //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible\n body.style.overflow = docElement.style.overflow = 'hidden';\n docElement.appendChild(body);\n }\n\n return docOverflow;\n}\n\nfunction resetFakeBody (body, docOverflow) {\n if (body.fake) {\n body.remove();\n docElement.style.overflow = docOverflow;\n // Trigger layout so kinetic scrolling isn't disabled in iOS6+\n // eslint-disable-next-line\n docElement.offsetHeight;\n }\n}\n\n// get css-calc \n\nfunction calc() {\n var doc = document, \n body = getBody(),\n docOverflow = setFakeBody(body),\n div = doc.createElement('div'), \n result = false;\n\n body.appendChild(div);\n try {\n var str = '(10px * 10)',\n vals = ['calc' + str, '-moz-calc' + str, '-webkit-calc' + str],\n val;\n for (var i = 0; i < 3; i++) {\n val = vals[i];\n div.style.width = val;\n if (div.offsetWidth === 100) { \n result = val.replace(str, ''); \n break;\n }\n }\n } catch (e) {}\n \n body.fake ? resetFakeBody(body, docOverflow) : div.remove();\n\n return result;\n}\n\n// get subpixel support value\n\nfunction percentageLayout() {\n // check subpixel layout supporting\n var doc = document,\n body = getBody(),\n docOverflow = setFakeBody(body),\n wrapper = doc.createElement('div'),\n outer = doc.createElement('div'),\n str = '',\n count = 70,\n perPage = 3,\n supported = false;\n\n wrapper.className = \"tns-t-subp2\";\n outer.className = \"tns-t-ct\";\n\n for (var i = 0; i < count; i++) {\n str += '
';\n }\n\n outer.innerHTML = str;\n wrapper.appendChild(outer);\n body.appendChild(wrapper);\n\n supported = Math.abs(wrapper.getBoundingClientRect().left - outer.children[count - perPage].getBoundingClientRect().left) < 2;\n\n body.fake ? resetFakeBody(body, docOverflow) : wrapper.remove();\n\n return supported;\n}\n\nfunction mediaquerySupport () {\n if (window.matchMedia || window.msMatchMedia) {\n return true;\n }\n \n var doc = document,\n body = getBody(),\n docOverflow = setFakeBody(body),\n div = doc.createElement('div'),\n style = doc.createElement('style'),\n rule = '@media all and (min-width:1px){.tns-mq-test{position:absolute}}',\n position;\n\n style.type = 'text/css';\n div.className = 'tns-mq-test';\n\n body.appendChild(style);\n body.appendChild(div);\n\n if (style.styleSheet) {\n style.styleSheet.cssText = rule;\n } else {\n style.appendChild(doc.createTextNode(rule));\n }\n\n position = window.getComputedStyle ? window.getComputedStyle(div).position : div.currentStyle['position'];\n\n body.fake ? resetFakeBody(body, docOverflow) : div.remove();\n\n return position === \"absolute\";\n}\n\n// create and append style sheet\nfunction createStyleSheet (media, nonce) {\n // Create the