Skip to content

Commit

Permalink
GH-321: Resize Callout image to parent height
Browse files Browse the repository at this point in the history
  • Loading branch information
wesleyboar committed Aug 23, 2021
1 parent fb1bfc3 commit bba22ef
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 4 deletions.
6 changes: 5 additions & 1 deletion taccsite_cms/contrib/taccsite_callout/cms_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ class TaccsiteCalloutPlugin(CMSPluginBase):
'description': TEXT_FOR_NESTED_PLUGIN_CONTENT_SWAP.format(
element='an image',
plugin_name='Image'
) + '\
<br />\
When the image resize field is checked, the image may disappear after saving this plugin. Reload the page to reload the image.',
'fields': (
'resize_figure_to_fit',
),
'fields': (),
}),
(_('Advanced settings'), {
'classes': ('collapse',),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 2.2.16 on 2021-08-23 18:47

from django.db import migrations, models


class Migration(migrations.Migration):

replaces = [('taccsite_callout', '0002_taccsitecallout_resize_figure_to_fit'), ('taccsite_callout', '0003_auto_20210823_1345')]

dependencies = [
('taccsite_callout', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='taccsitecallout',
name='resize_figure_to_fit',
field=models.BooleanField(default=True, help_text='Make image shorter or taller to match the height of text beside it.', verbose_name='Resize any image to fit'),
),
]
7 changes: 7 additions & 0 deletions taccsite_cms/contrib/taccsite_callout/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ class TaccsiteCallout(CMSPlugin):
max_length=200,
)

resize_figure_to_fit = models.BooleanField(
verbose_name=_('Resize any image to fit'),
help_text=_('Make image shorter or taller to match the height of text beside it.'),
blank=False,
default=True
)

attributes = fields.AttributesField()

def get_short_description(self):
Expand Down
29 changes: 26 additions & 3 deletions taccsite_cms/contrib/taccsite_callout/templates/callout.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
{% load cms_tags %}
{% load cms_tags static %}

<aside {# class="c-callout" #}{{ instance.attributes_str }}>
<aside {# class="c-callout" #}{{ instance.attributes_str }}
{% if instance.resize_figure_to_fit %}
id="callout-{{ instance.id }}"
{% endif %}
>

<h2 class="c-callout__title">{{ instance.title }}</h2>
<p class="c-callout__desc">{{ instance.description }}</p>

{% if image_plugin %}
<figure class="c-callout__figure">
<figure class="c-callout__figure"
{% if instance.resize_figure_to_fit %}
data-transform="size-content-to-fit" hidden
{% endif %}
>
{% for plugin_instance in instance.child_plugin_instances %}
{% render_plugin plugin_instance %}
{% endfor %}
</figure>
{% endif %}

</aside>

{% if instance.resize_figure_to_fit %}
<script type="module">
import { SizeContentToFit } from '{% static "site_cms/js/modules/elementTransformer.js" %}';

// HACK: GH-320: Pause to ensure resize occurs while in CMS page edit mode
window.setTimeout(() => {
const container = document.querySelector(
'#callout-' + '{{ instance.id }} [data-transform="size-content-to-fit"]'
);

new SizeContentToFit(container);
}, 0);
</script>
{% endif %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.16 on 2021-08-23 18:39

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('taccsite_data_list', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='taccsitedatalistitem',
name='key',
field=models.CharField(blank=True, help_text='A label for the data value.', max_length=50, verbose_name='Label'),
),
]
98 changes: 98 additions & 0 deletions taccsite_cms/static/site_cms/js/modules/elementTransformer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/**
* Resize content to fit parent height
*
* - Manipulates attributes within existing markup.
* - Size is NOT dynamically updated after initial load.
* @module elementTransformer
*/

/** Resize first child element to match parent height (track state in markup) */
export class SizeContentToFit {



// FAQ: Offers clarity of intent and consistency with state attr.
// NOTE: Could faciliate programmatic transforms (like as a plugin option)
/** A suggested selector to match the container */
static containerSelector = '[data-transform="size-content-to-fit"]';



/**
* Initialize and resize
* @param {HTMLElement} container - The direct parent of the content to resize
*/
constructor (container) {
/** The `HTMLElement` containing the content to resize */
this.container = container;
/** The `HTMLElement` to resize */
this.content = container.querySelector(':scope > *');

// GH-320: Test whether `this.content` was in the DOM at runtime
// FAQ: Use `cloneNode` to NOT watch element reference that is updated later
// console.log({
// container: this.container.cloneNode(true),
// content: this.content.cloneNode(true)
// });

this.resizeContent();
}



/** Mark transformation as in the given state */
setState(state) {
this.container.dataset.transformState = state;
}

/** Mark transformation as NOT in the given state */
removeState(state) {
// NOTE: Multiple states are not supported, so there is no use for `state`
this.container.dataset.transformState = null;
}

/** Whether transformation is in given state */
isState(state) {
return (this.container.dataset.transformState == state);
}

/** Whether to resize the content */
shouldResizeContent() {
if (this.container.getAttribute('hidden') !== null) {
this.content.style.offsetHeight = '0';
this.container.removeAttribute('hidden');
}
}


/** Resize the content */
resizeContent() {
/* To prevent natural height of content from increasing container height */
/* FAQ: Module will set wrong height if content is taller than is desired */
if (this.container.getAttribute('hidden') !== null) {
this.content.style.height = '0';
this.container.removeAttribute('hidden');
}

/* To inform observers that this module is active */
this.setState('resizing-content');

/* To make container (and its content) the same height as a root element */
/* FAQ: Given tall content, figure height equals content height */
/* FAQ: Given hidden content, figure height equals desired content height */
this.container.style.height = '100%';
this.content.style.height = this.container.offsetHeight + 'px';
this.container.style.height = null;

/* To clean up mess (only if it appears to be the mess of this module) */
if (this.isState('resizing-content')) {
this.removeState('resizing-content');
if ( ! this.container.getAttribute('style')) {
this.container.removeAttribute('style');
}
}

/* To inform observers that this module is done */
this.setState('complete');
}
}

0 comments on commit bba22ef

Please sign in to comment.