diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 750a692..f641119 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -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
diff --git a/README.md b/README.md
index b355e08..1db4edf 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Inspector
-An extension to inspect details of elements.
+**Inspector** is an extension to inspect the details of Adapt elements.
## Installation
@@ -67,3 +67,14 @@ An extension to inspect details of elements.
');
+ 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;
diff --git a/js/InspectorView.js b/js/InspectorView.js
new file mode 100644
index 0000000..2dce72c
--- /dev/null
+++ b/js/InspectorView.js
@@ -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;
diff --git a/js/adapt-inspector.js b/js/adapt-inspector.js
index d06d10e..9831034 100644
--- a/js/adapt-inspector.js
+++ b/js/adapt-inspector.js
@@ -1,198 +1,38 @@
-define([
- 'core/js/adapt',
- 'core/js/device'
-], function(Adapt, device) {
-
- const InspectorView = Backbone.View.extend({
-
- className: 'inspector',
-
- ids: [],
-
- initialize: function() {
- const config = Adapt.config.get('_inspector');
- if (device.touch && config._isDisabledOnTouch) return;
-
- this.listenTo(Adapt, {
- 'inspector:id': this.pushId,
- 'inspector:hover': this.setVisibility,
- 'inspector:touch': this.updateInspector,
- 'device:resize': this.onResize,
- remove: this.remove
- }).render();
- },
-
- events: {
- mouseleave: 'onLeave'
- },
-
- render: function() {
- $('#wrapper').append(this.$el);
- },
-
- pushId: function(id) {
- this.ids.push(id);
- },
-
- setVisibility: function() {
- if (this.$el.is(':hover')) return;
-
- for (let i = this.ids.length - 1; i >= 0; --i) {
- const $hovered = $("[data-adapt-id='" + this.ids[i] + "']:hover");
-
- if ($hovered.length) return this.updateInspector($hovered);
- }
-
- $('.inspector-visible').removeClass('inspector-visible');
- this.$el.hide();
- },
-
- updateInspector: function($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: function($hovered) {
- const checkOverlap = function() {
- const $element = $(this);
-
- const isOverlapped = $element.height() && _.isEqual($element.offset(), $hovered.offset()) && $element.width() === $hovered.width();
-
- if (isOverlapped) $hovered = $hovered.add($element);
- };
-
- for (let i = this.ids.length - 1; i >= 0; --i) {
- $("[data-adapt-id='" + this.ids[i] + "']").each(checkOverlap);
- }
-
- return $hovered;
- },
-
- onResize: function() {
- const $hovered = $('.inspector-visible');
-
- if (!$hovered.length) return;
-
- $hovered.removeClass('inspector-visible');
- this.updateInspector($hovered.last());
- },
-
- onLeave: function() {
- _.defer(this.setVisibility.bind(this));
- }
-
- });
-
- const InspectorContainerView = Backbone.View.extend({
-
- initialize: function() {
- const id = this.model.get('_id');
-
- this.listenTo(Adapt, 'remove', this.remove).addTracUrl(id);
- this.$el.data(this.model);
- Adapt.trigger('inspector:id', id);
- },
-
- events: {
- mouseenter: 'onHover',
- mouseleave: 'onHover',
- touchend: 'onTouch'
- },
-
- addTracUrl: function(id) {
- 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 = $('
');
- 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: function() {
- _.defer(function() { Adapt.trigger('inspector:hover'); });
- },
-
- onTouch: function(event) {
- if (event.originalEvent.stopInspectorPropagation) return;
-
- event.originalEvent.stopInspectorPropagation = true;
-
- if (!$(event.target).is('[class*=inspector-]')) {
- Adapt.trigger('inspector:touch', this.$el);
- }
- }
-
- });
+import Adapt from 'core/js/adapt';
+import location from 'core/js/location';
+import InspectorContainerView from './InspectorContainerView';
+import InspectorView from './InspectorView';
+
+class Inspector extends Backbone.Controller {
+ initialize() {
+ this.listenToOnce(Adapt, 'app:dataReady', this.initInspector);
+ }
- function getLocationString(context) {
+ getLocationString(context) {
const data = context.data.root;
const id = data.length ? data[0]._id : data._id;
- const location = Adapt.location;
const locationId = location._currentId;
const locationType = location._contentType;
return id !== locationId ? ' (' + locationType + ' ' + locationId + ')' : '';
}
- Adapt.once('app:dataReady', function() {
+ initInspector() {
const config = Adapt.config.get('_inspector');
-
if (!config || !config._isEnabled) return;
- const views = config._elementsToInspect || [ 'menu', 'menuItem', 'page', 'article', 'block', 'component' ];
-
- const eventList = views.map(function(view) { return view + 'View:postRender'; });
+ const defaultElements = [ 'menu', 'menuItem', 'page', 'article', 'block', 'component' ];
+ const views = config._elementsToInspect || defaultElements;
+ const eventList = views.map(view => { return view + 'View:postRender'; });
- Handlebars.registerHelper('inspector_location', getLocationString);
+ Handlebars.registerHelper('inspector_location', this.getLocationString);
- Adapt.on('router:location', function() {
+ Adapt.on('router:location', () => {
new InspectorView();
- }).on(eventList.join(' '), function(view) {
+ }).on(eventList.join(' '), (view) => {
new InspectorContainerView({ el: view.$el, model: view.model });
});
- });
+ }
+}
-});
+export default new Inspector();