Skip to content

Commit bbcd61b

Browse files
committed
support empty elements
1 parent f1060c6 commit bbcd61b

File tree

2 files changed

+85
-11
lines changed

2 files changed

+85
-11
lines changed

.eslintrc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,20 @@
22
"env": {
33
"es6": true,
44
"browser": true
5+
},
6+
"parserOptions": {
7+
"ecmaVersion": 2020
8+
},
9+
"extends": [
10+
"eslint:recommended"
11+
],
12+
"rules": {
13+
"no-redeclare": "off",
14+
"no-cond-assign": "off",
15+
"no-prototype-builtins": "off"
16+
},
17+
"globals": {
18+
"chrome": "readonly",
19+
"google": "readonly"
520
}
621
}

positionable.js

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,12 +1355,17 @@ class OutputManager {
13551355
getSelectorFromElement(element, fallback) {
13561356
var el, type, selector;
13571357

1358-
el = element.el;
1358+
el = element.getTargetElement();
13591359
type = this.getSelectorType(el);
13601360
selector = this.getSelectorForType(type, el);
13611361

13621362
if (!selector && (fallback || type !== Settings.OUTPUT_SELECTOR_NONE)) {
1363-
selector = el.tagName.toLowerCase();
1363+
let tag = el.tagName.toLowerCase();
1364+
if (tag === 'input') {
1365+
selector = `input[type="${el.type}"]`;
1366+
} else {
1367+
selector = tag;
1368+
}
13641369
}
13651370
return selector;
13661371
}
@@ -2308,7 +2313,7 @@ class PositionableElementManager {
23082313
els = [];
23092314
}
23102315

2311-
for(let i = 0, el; el = els[i]; i++) {
2316+
for (let el of els) {
23122317
if (includeSelector || this.canAutoAddElement(el)) {
23132318
this.elements.push(new PositionableElement(this, el));
23142319
}
@@ -2612,7 +2617,7 @@ class DragTarget extends BrowserEventTarget {
26122617

26132618
setupInteractiveElements() {
26142619
var els = this.el.querySelectorAll(DragTarget.INTERACTIVE_ELEMENTS_SELECTOR);
2615-
for (let i = 0, el; el = els[i]; i++) {
2620+
for (let el of els) {
26162621
var element = new BrowserEventTarget(el);
26172622
element.stopPropagation('mousedown');
26182623
element.stopPropagation('click');
@@ -4036,7 +4041,7 @@ class Settings {
40364041
parseGroupingMap(str) {
40374042
var lines = str.split('\n'), data = {};
40384043
lines = lines.filter(l => l);
4039-
for (let i = 0, line; line = lines[i]; i++) {
4044+
for (let line of lines) {
40404045
var match, key, val;
40414046
match = line.match(/\s*([^:]+):\s*([^;]+)/);
40424047
if (!match) {
@@ -4192,7 +4197,7 @@ class SettingsForm extends BrowserEventTarget {
41924197
if (val) {
41934198
switch (control.type) {
41944199
case SettingsForm.SELECT_ONE:
4195-
for (var i = 0, option; option = control.options[i]; i++) {
4200+
for (let option of control.options) {
41964201
if (option.value === val) {
41974202
option.selected = true;
41984203
}
@@ -4303,7 +4308,7 @@ class SettingsForm extends BrowserEventTarget {
43034308

43044309
getFirstControl() {
43054310
var els = this.el.elements;
4306-
for (var i = 0, control; control = els[i]; i++) {
4311+
for (let control of els) {
43074312
if (control.id) {
43084313
return control;
43094314
}
@@ -4312,7 +4317,7 @@ class SettingsForm extends BrowserEventTarget {
43124317

43134318
forEachControl(fn) {
43144319
var els = this.el.elements;
4315-
for (var i = 0, control; control = els[i]; i++) {
4320+
for (let control of els) {
43164321
if (control.id) {
43174322
fn(control);
43184323
}
@@ -4355,7 +4360,7 @@ class LinkedSelect extends BrowserEventTarget {
43554360
setup() {
43564361
this.linked = {};
43574362
var els = this.el.parentNode.querySelectorAll('[data-linked-option]');
4358-
for (var i = 0, el; el = els[i]; i++) {
4363+
for (let el of els) {
43594364
this.linked[el.dataset.linkedOption] = new Element(el);
43604365
}
43614366
this.bindEvent('change', this.onChange);
@@ -4532,6 +4537,23 @@ class CopyAnimation extends Animation {
45324537

45334538
/*-------------------------] PositionableElement [--------------------------*/
45344539

4540+
const EMPTY_ELEMENT_TAGS = [
4541+
'AREA',
4542+
'BASE',
4543+
'BR',
4544+
'COL',
4545+
'EMBED',
4546+
'HR',
4547+
'IMG',
4548+
'INPUT',
4549+
'LINK',
4550+
'META',
4551+
'PARAM',
4552+
'SOURCE',
4553+
'TRACK',
4554+
'WBR',
4555+
];
4556+
45354557
class PositionableElement extends BrowserEventTarget {
45364558

45374559
static get UI_FOCUSED_CLASS() { return 'ui--focused'; }
@@ -4546,6 +4568,8 @@ class PositionableElement extends BrowserEventTarget {
45464568
this.states = [];
45474569

45484570
this.setup();
4571+
4572+
return this.linkedInterface || this;
45494573
}
45504574

45514575
// --- Manipulation
@@ -4631,6 +4655,10 @@ class PositionableElement extends BrowserEventTarget {
46314655

46324656
// --- Other
46334657

4658+
getTargetElement() {
4659+
return this.linkedEl || this.el;
4660+
}
4661+
46344662
getRotation() {
46354663
return this.cssTransform.getRotation();
46364664
}
@@ -4733,7 +4761,11 @@ class PositionableElement extends BrowserEventTarget {
47334761
setup() {
47344762
this.setupEvents();
47354763
this.setupInitialState();
4736-
this.injectInterface();
4764+
if (this.isEmptyElement()) {
4765+
this.createLinkedInterface();
4766+
} else {
4767+
this.injectInterface();
4768+
}
47374769
}
47384770

47394771
setupEvents() {
@@ -4750,6 +4782,28 @@ class PositionableElement extends BrowserEventTarget {
47504782
this.cssBackgroundImage = CSSBackgroundImage.fromMatcher(matcher);
47514783
}
47524784

4785+
isEmptyElement() {
4786+
return EMPTY_ELEMENT_TAGS.includes(this.el.tagName);
4787+
}
4788+
4789+
createLinkedInterface() {
4790+
const { el } = this;
4791+
var style = window.getComputedStyle(el);
4792+
var div = document.createElement('div');
4793+
el.parentNode.append(div);
4794+
div.style.position = style.position;
4795+
div.style.top = style.top;
4796+
div.style.left = style.left;
4797+
div.style.width = style.width;
4798+
div.style.height = style.height;
4799+
div.style.margin = style.margin;
4800+
div.style.padding = style.padding;
4801+
div.style.border = style.border;
4802+
div.style.borderColor = 'transparent';
4803+
this.linkedInterface = new PositionableElement(this.listener, div);
4804+
this.linkedInterface.linkedEl = this.el;
4805+
}
4806+
47534807
injectInterface() {
47544808
// As the UI is injected before any other elements, placing it at the
47554809
// top level means that nested positionable elements will override it
@@ -5078,6 +5132,9 @@ class PositionableElement extends BrowserEventTarget {
50785132

50795133
renderBox() {
50805134
this.cssBox.render(this.el.style);
5135+
if (this.linkedEl) {
5136+
this.cssBox.render(this.linkedEl.style);
5137+
}
50815138
if (this.isPeeking) {
50825139
var p = this.getPeekDimensions();
50835140
this.el.style.width = p.x + 'px';
@@ -5087,6 +5144,9 @@ class PositionableElement extends BrowserEventTarget {
50875144

50885145
renderTransform() {
50895146
this.cssTransform.render(this.el.style);
5147+
if (this.linkedEl) {
5148+
this.cssTransform.render(this.linkedEl.style);
5149+
}
50905150
}
50915151

50925152
renderBackgroundPosition() {
@@ -7346,5 +7406,4 @@ function roundWithPrecision(n, precision) {
73467406
return Math.round(n * mult) / mult;
73477407
}
73487408

7349-
73507409
window.AppController = AppController;

0 commit comments

Comments
 (0)