Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update: Migrate to ES6 syntax (fixes #6) #7

Merged
merged 10 commits into from
Jul 3, 2024
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* A sentence describing each fix

### Update
* A sentence describing each udpate
* A sentence describing each update

### New
* A sentence describing each new feature
Expand Down
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Inspector

An extension to inspect details of elements.
**Inspector** is an extension to inspect the details of Adapt elements.

## Installation

Expand Down Expand Up @@ -67,3 +67,14 @@ An extension to inspect details of elements.
<td><code>[ "menu", "menuItem", "page", "article", "block", "component" ]</code></td>
</tr>
</table>

## Limitations

No known limitations.

----------------------------

**Author / maintainer:** CGKineo<br>
**Accessibility support:** WAI AA<br>
**RTL support:** Yes<br>
**Cross-platform coverage:** Chrome, Chrome for Android, Firefox (ESR + latest version), Edge, Safari for macOS/iOS/iPadOS, Opera<br>
59 changes: 59 additions & 0 deletions js/InspectorContainerView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import Adapt from 'core/js/adapt';

class InspectorContainerView extends Backbone.View {
initialize() {
const id = this.model.get('_id');

this.listenTo(Adapt, 'remove', this.remove);
this.addTracURL();
this.$el.data(this.model);
Adapt.trigger('inspector:id', id);
}

events() {
return {
mouseenter: 'onHover',
mouseleave: 'onHover',
touchend: 'onTouch'
};
}

addTracURL() {
const config = Adapt.config.get('_inspector')._trac;
if (!config || !config._isEnabled) return;

const params = config._params || {
summary: '{{_id}}{{#if displayTitle}} {{{displayTitle}}}{{/if}}{{inspector_location}}'
};

const $div = $('<div>');
const data = this.model.toJSON();
let tracUrl = `${config._url}/newticket?`;

for (const key in params) {
if (!Object.prototype.hasOwnProperty.call(params, key)) continue;

const value = $div.html(Handlebars.compile(params[key])(data)).text();

tracUrl += `&${key}=${encodeURIComponent(value)}`;
}

this.model.set('_tracUrl', tracUrl);
}

onHover() {
_.defer(() => Adapt.trigger('inspector:hover'));
}

onTouch(event) {
if (event.originalEvent.stopInspectorPropagation) return;

event.originalEvent.stopInspectorPropagation = true;

if ($(event.target).is('[class*=inspector-]')) return;

Adapt.trigger('inspector:touch', this.$el);
}
}

export default InspectorContainerView;
115 changes: 115 additions & 0 deletions js/InspectorView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import Adapt from 'core/js/adapt';
import device from 'core/js/device';

class InspectorView extends Backbone.View {
className() {
return 'inspector';
}

events() {
return {
mouseleave: 'onLeave'
};
}

initialize() {
const config = Adapt.config.get('_inspector');
if (device.touch && config._isDisabledOnTouch) return;

_.bindAll(this, 'onLeave', 'pushId', 'setVisibility', 'updateInspector', 'onResize', 'remove');

this.listenTo(Adapt, {
'inspector:id': this.pushId,
'inspector:hover': this.setVisibility,
'inspector:touch': this.updateInspector,
'device:resize': this.onResize,
remove: this.remove
}).render();

this.ids = [];
}

render() {
$('#wrapper').append(this.$el);
};

pushId(id) {
this.ids.push(id);
}

setVisibility() {
if (this.$el.is(':hover')) return;

const reversedIds = this.ids.toReversed();
for (const id of reversedIds) {
const $hovered = $(`[data-adapt-id="${id}"]:hover`);

if ($hovered.length) return this.updateInspector($hovered);
}

$('.inspector-visible').removeClass('inspector-visible');
this.$el.hide();
}

updateInspector($hovered) {
const $previous = $('.inspector-visible');
if ($hovered.is($previous.last())) return;

const data = [];
const template = Handlebars.templates.inspector;

$previous.removeClass('inspector-visible');

this.addOverlappedElements($hovered).each(function() {
const $element = $(this);
const attributes = $element.data().attributes;
if (!attributes) return;

data.push(attributes);
$element.addClass('inspector-visible');
});

this.$el.html(template(data)).removeAttr('style').removeClass('inline');

const offset = $hovered.offset();
const offsetTop = offset.top;
const targetTop = offsetTop - this.$el.outerHeight();
const shouldBeInline = targetTop < 0;

this.$el.css({
top: shouldBeInline ? offsetTop : targetTop,
left: offset.left + $hovered.outerWidth() / 2 - this.$el.width() / 2
}).toggleClass('inline', shouldBeInline);
}

addOverlappedElements($hovered) {
this.ids.forEach((id) => {
const $element = $(`[data-adapt-id="${id}"]`);
this.checkOverlap($element, $hovered);
});

return $hovered;
}

checkOverlap($element, $hovered) {
const areOffsetsEqual = _.isEqual($element.offset(), $hovered.offset());
const areWidthsEqual = $element.width() === $hovered.width();
const isOverlapped = $element.height() && areOffsetsEqual && areWidthsEqual;

if (isOverlapped) $hovered = $hovered.add($element);
}

onResize() {
const $hovered = $('.inspector-visible');
if (!$hovered.length) return;

$hovered.removeClass('inspector-visible');
this.updateInspector($hovered.last());
}

onLeave() {
_.defer(this.setVisibility.bind(this));
}
};

export default InspectorView;
Loading
Loading