Skip to content

Commit

Permalink
make sul-embed work with exhibits select image section
Browse files Browse the repository at this point in the history
  • Loading branch information
dnoneill committed Dec 17, 2024
1 parent 3183b8d commit c085822
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 7 deletions.
1 change: 1 addition & 0 deletions app/components/embed/m3_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
id='sul-embed-m3'
class='m3'
data-m3-uri='<%= viewer.manifest_json_url %>'
data-viewer-config='<%= viewer.iiif_initial_viewer_config %>'
data-canvas-id='<%= viewer.canvas_id %>'
data-canvas-index='<%= viewer.canvas_index %>'
data-hide-title='<%= viewer.embed_request.hide_title? %>'
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/embed_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def linted_params
rescue URI::InvalidURIError
raise ActionController::BadRequest
end
params.permit(:url, :maxwidth, :maxheight, :format, :fullheight, :new_component,
params.permit(:url, :maxwidth, :maxheight, :format, :fullheight, :new_component, :iiif_initial_viewer_config,
:hide_title, :hide_embed, :hide_download, :hide_search, :min_files_to_search,
:canvas_id, :canvas_index, :search, :suggested_search, :image_tools, :cdl_hold_record_id)
end
Expand Down
42 changes: 41 additions & 1 deletion app/javascript/src/modules/m3_viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import miradorZoomBugPlugin from '../plugins/miradorZoomBugPlugin'
import embedModePlugin from '../plugins/embedModePlugin'
import analyticsPlugin from '../plugins/analyticsPlugin'
import cdlAuthPlugin from '../plugins/cdlAuthPlugin'
import xywhPlugin from '../plugins/xywhPlugin'
import { getExportableState } from 'mirador/dist/es/src/state/selectors'

export default {
init: function() {
Expand All @@ -30,7 +32,10 @@ export default {
sideBarPanel = 'attribution'
}

Mirador.viewer({
let viewerConfig
if (data.viewerConfig && data.viewerConfig !== 'undefined') { viewerConfig = JSON.parse(decodeURIComponent(data.viewerConfig)) }

const viewerInstance = Mirador.viewer({
id: 'sul-embed-m3',
miradorDownloadPlugin: {
restrictDownloadOnSizeDefinition: true,
Expand Down Expand Up @@ -80,6 +85,7 @@ export default {
suggestedSearches: data.suggestedSearch.length > 0 ? [data.suggestedSearch] : null,
loadedManifest: data.m3Uri,
canvasIndex: Number(data.canvasIndex),
initialViewerConfig: viewerConfig,
canvasId: data.canvasId,
...(cdl && {
cdl: {
Expand Down Expand Up @@ -135,5 +141,39 @@ export default {
analyticsPlugin,
xywhPlugin,
].filter(Boolean))

window.addEventListener('message', (event) => {
const regex = /^(stanford\.edu|[\w-]+\.stanford\.edu)$/
if (regex.exec(event.origin) === null && process.env.RAILS_ENV !== 'development') {
return
}

if (event && event.data) {
let parsedData
try {
parsedData = typeof event.data === 'string' ? JSON.parse(event.data) : event.data
} catch (error) {
console.error('Failed to parse event data:', error)
return // Exit if parsing fails
}
if (parsedData.type === "requestState") {
const currentState = viewerInstance.store.getState()
const exportableState = getExportableState(currentState)

const imageUrl = viewerInstance.container.querySelector('[data-full-image]').dataset.fullImage.split('*')
const canvasIndex = viewerInstance.container.querySelector('.mirador-canvas-count').textContent.split(' of')[0]

// Send the state back to the parent window
window.parent.postMessage(
JSON.stringify({
type: 'stateResponse',
data: {...exportableState, ...{'iiif_images': imageUrl, 'canvas_index': canvasIndex}},
source: 'sul-embed-m3',
}),
event.origin
)
}
}
})
}
}
32 changes: 29 additions & 3 deletions app/javascript/src/plugins/xywhPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,39 @@ const convertToIIIFCoords = (bounds) => {
return Math.round(bounds);
};

const convertToRegionUrl = (imageBounds, image_url) => {
const xywh = `${convertToIIIFCoords(imageBounds.x)},${convertToIIIFCoords(imageBounds.y)},${convertToIIIFCoords(imageBounds.width)},${convertToIIIFCoords(imageBounds.height)}`;
return image_url + `/${xywh}/full/0/default.jpg`
};

const onViewportChange = (event) => {
const viewer = event.eventSource;
const { viewport } = viewer;

const imageBounds = viewport.viewportToImageRectangle(viewport.getBounds());
const parsedBounds = `${convertToIIIFCoords(imageBounds.x)},${convertToIIIFCoords(imageBounds.y)},${convertToIIIFCoords(imageBounds.width)},${convertToIIIFCoords(imageBounds.height)}`;
viewer.element.parentNode.setAttribute('data-xywh-coords', parsedBounds);
let full_image = ''
const itemCount = viewport.viewer.world.getItemCount();

if (itemCount > 1){
const page1 = viewport.viewer.world.getItemAt(0);
const page2 = viewport.viewer.world.getItemAt(1);
const page1_vars = {x: 0, y: 0, height: page1.source.height, width: page1.source.width, id: page1.source._id}
const page2_vars = {x: page1_vars['width'], y: page1_vars['height'], height: page2.source.height, width: page2.source.width, id: page2.source._id}
let page1_bounds = page1.viewportToImageRectangle(viewport.getBounds());
let page2_bounds = page2.viewportToImageRectangle(viewport.getBounds());
let visible_pages =[]
if (page1_bounds.x <= page1.source.width){
visible_pages.push(convertToRegionUrl(page1_bounds, page1.source._id))
}
if (page1.source.width - page1_bounds.x < page1_bounds.width || page2_bounds.x > 0) {
page2_bounds.width = page2_bounds.width - (page1.source.width - page1_bounds.x);
visible_pages.push(convertToRegionUrl(page2_bounds, page2.source._id))
}
full_image = visible_pages.join("*")
} else {
const imageBounds = viewport.viewportToImageRectangle(viewport.getBounds());
full_image = convertToRegionUrl(imageBounds, viewport.viewer.source._id)
}
viewer.element.parentNode.setAttribute('data-full-image', full_image);
};

function XywhDataAttributePlugin({ viewer, windowId }) {
Expand Down
3 changes: 2 additions & 1 deletion app/viewers/embed/viewer/m3_viewer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
module Embed
module Viewer
class M3Viewer < CommonViewer
delegate :search, :suggested_search, :canvas_id, :cdl_hold_record_id, to: :embed_request
delegate :search, :suggested_search, :canvas_id, :cdl_hold_record_id, :iiif_initial_viewer_config,
to: :embed_request

def component
M3Component
Expand Down
1 change: 1 addition & 0 deletions app/views/embed/iiif.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
data-search='<%= @embed_request.search %>'
data-suggested-search='<%= @embed_request.suggested_search %>'
data-image-tools='<%= @embed_request.image_tools %>'
data-viewer-config='<%= @embed_request.iiif_initial_viewer_config %>'
style='height:100%; width:100%'>
</div>

Expand Down
7 changes: 6 additions & 1 deletion lib/embed/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ def as_url_params
:min_files_to_search,
:canvas_id, :canvas_index,
:search, :suggested_search,
:image_tools
:image_tools,
:iiif_initial_viewer_config
)

if p.respond_to? :permit!
Expand Down Expand Up @@ -107,6 +108,10 @@ def image_tools
params[:image_tools]
end

def iiif_initial_viewer_config
params[:iiif_initial_viewer_config]
end

def validate!(url_parameter: true, url_scheme: true, format: true)
require_url_parameter if url_parameter
validate_url_scheme if url_scheme
Expand Down

0 comments on commit c085822

Please sign in to comment.