pageflow-linkmap-page 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2ace1b5edf88295b6d1e8d602bdf11cfd4f28800
4
- data.tar.gz: f264b4eac26073ef030b801d3cf17e34299030ee
3
+ metadata.gz: 4b73e3d49c82b5876fce90056bcb4fe58771fc34
4
+ data.tar.gz: 6d38604747a162226fc45fd9b2b6c1d56c596ea8
5
5
  SHA512:
6
- metadata.gz: f0b5f204c209625f2621577553bfaf9626ef70d74b93eaabdf8745948a76a5c37c5cec3b18c333a0c6f6bc2743e2c8ad0bcb33d3ed82de46073b36db18a472fe
7
- data.tar.gz: e37fc9d1c98a09d9e562beb7324985482c508c985cd736b60553ef68e7ebae30498e8312a9955ca2a26805cdf1669a2bb8b14f506bdf556100fd27e4bfd3a861
6
+ metadata.gz: 9a18d92640f24a2539bd1d4f4c9742d7549cdc5c86e56cb7087be871816787f28568e6fb291fdcdee800ff4e0e4cfea87e415127540e8e83ffb9609d9caee176
7
+ data.tar.gz: 84e8646c2e3ca811472f92adc70b6f2df67a3146e71775003aab7b298ce1e38dd95368f0fa9f1239baf41efe244dfc0959825f9561899874802f4e0c5a018be7
@@ -1,34 +1,20 @@
1
1
  # CHANGELOG
2
2
 
3
- ### Version 1.0.0
3
+ ### Version 1.1.0
4
4
 
5
- 2017-08-11
5
+ 2017-10-09
6
6
 
7
- [Compare changes](https://github.com/codevise/pageflow-linkmap-page/compare/0-2-stable...v1.0.0)
7
+ [Compare changes](https://github.com/codevise/pageflow-linkmap-page/compare/1-0-stable...v1.1.0)
8
8
 
9
- ##### Manual Update Step
10
-
11
- The plugin now provides additional routes and migrations. Mount the engine:
12
-
13
- # config/routes.rb
14
- mount Pageflow::LinkmapPage::Engine, at: '/linkmap_page'
15
-
16
- Install and run migrations:
17
-
18
- $ rake pageflow_linkmap_page:install:migrations
19
- $ rake db:migrate
20
-
21
- ##### Features
22
-
23
- - Support mask image for non rectangular areas
24
- ([#22](https://github.com/codevise/pageflow-linkmap-page/pull/22))
25
- - Add support for pageflow-external-links 1.x
26
- ([#26](https://github.com/codevise/pageflow-linkmap-page/pull/26))
27
- - Rename the last `css.scss` files
28
- ([#25](https://github.com/codevise/pageflow-linkmap-page/pull/25))
29
- - Require pageflow 12
30
- ([#24](https://github.com/codevise/pageflow-linkmap-page/pull/24))
9
+ - Fix hover video variant in published entry
10
+ ([#29](https://github.com/codevise/pageflow-linkmap-page/pull/29))
11
+ - Make mask image url template generation more robust
12
+ ([#30](https://github.com/codevise/pageflow-linkmap-page/pull/30))
13
+ - Improve mask features of hotspot page
14
+ ([#28](https://github.com/codevise/pageflow-linkmap-page/pull/28))
15
+ - Ensure pageflow 12 is used in tests
16
+ ([#27](https://github.com/codevise/pageflow-linkmap-page/pull/27))
31
17
 
32
18
  See
33
- [0-2-stable branch](https://github.com/codevise/pageflow-linkmap-page/blob/0-2-stable/CHANGELOG.md)
19
+ [1-0-stable branch](https://github.com/codevise/pageflow-linkmap-page/blob/1-0-stable/CHANGELOG.md)
34
20
  for previous changes.
data/Gemfile CHANGED
@@ -5,10 +5,5 @@ gemspec
5
5
 
6
6
  gem 'state_machine', git: 'https://github.com/codevise/state_machine.git'
7
7
 
8
- gem 'pageflow', '0.11.3'
9
- gem 'pageflow-support', '0.11.3'
10
-
11
- gem 'teaspoon', git: 'https://github.com/modeset/teaspoon'
12
-
13
- gem "spring-commands-rspec", group: :development
14
- gem "spring-commands-teaspoon", group: :development
8
+ gem 'spring-commands-rspec', group: :development
9
+ gem 'spring-commands-teaspoon', group: :development
@@ -63,8 +63,10 @@
63
63
  }
64
64
 
65
65
  function generateMaskSprite(configuration, imageFile) {
66
+ // panorama_mask_url is available in Pageflow >= 12.1
66
67
  pageflow.linkmapPage.StoredMaskSprite
67
68
  .findOrCreateForImageFileId(imageFile.id,
69
+ imageFile.get('panorama_mask_url') ||
68
70
  imageFile.get('panorama_url'))
69
71
  .then(
70
72
  function(masks) {
@@ -78,6 +80,7 @@
78
80
  alert(I18n.t(error.i18nKey));
79
81
  }
80
82
  else {
83
+ alert(I18n.t('pageflow.linkmap_page.errors.mask_image_failed'));
81
84
  throw(error);
82
85
  }
83
86
  }
@@ -10,16 +10,28 @@ pageflow.linkmapPage.StoredMaskSprite = Backbone.Model.extend({
10
10
  pageflow.linkmapPage.StoredMaskSprite.findOrCreateForImageFileId = function(imageFileId, imageFileUrl) {
11
11
  return new $.Deferred(function(deferred) {
12
12
  pageflow.linkmapPage.Masks.loadColorMapImage(imageFileUrl).then(function(masks) {
13
- var storedMaskSprite = new pageflow.linkmapPage.StoredMaskSprite({
14
- image_file_id: imageFileId,
15
- attachment: masks.getSpriteDataUrl()
16
- });
13
+ try {
14
+ var storedMaskSprite = new pageflow.linkmapPage.StoredMaskSprite({
15
+ image_file_id: imageFileId,
16
+ attachment: masks.getSpriteDataUrl()
17
+ });
17
18
 
18
- storedMaskSprite.save(null, {
19
- success: function() {
20
- deferred.resolve(masks.serialize(storedMaskSprite.id));
21
- }
22
- });
19
+ storedMaskSprite.save(null, {
20
+ success: function() {
21
+ deferred.resolve(masks.serialize(storedMaskSprite.id));
22
+ },
23
+
24
+ error: function() {
25
+ deferred.reject({
26
+ message: 'Error saving mask sprite to the server.',
27
+ i18nKey: 'pageflow.linkmap_page.errors.saving_mask_image_failed'
28
+ });
29
+ }
30
+ });
31
+ }
32
+ catch (e) {
33
+ deferred.reject(e);
34
+ }
23
35
  }, deferred.reject);
24
36
  }).promise();
25
37
  };
@@ -36,7 +36,7 @@
36
36
  var area = widget.areaAt(widget.positionFromEvent(event));
37
37
 
38
38
  if (area.length) {
39
- area.first().trigger('linkmapareaclick');
39
+ area.first().trigger($.Event('linkmapareaclick', {originalEvent: event}));
40
40
  }
41
41
  else {
42
42
  widget._trigger('backgroundclick');
@@ -45,18 +45,6 @@
45
45
  return false;
46
46
  });
47
47
 
48
- this.element.on('touchstart', function(event) {
49
- var area = widget.areaAt(widget.positionFromEvent(event.originalEvent.touches[0]));
50
-
51
- var areaEvent = jQuery.Event('linkmapareatouchstart');
52
-
53
- area.first().trigger(areaEvent);
54
-
55
- if (areaEvent.isDefaultPrevented()) {
56
- event.preventDefault();
57
- }
58
- });
59
-
60
48
  this.element.on('mousemove mouseleave', function(event) {
61
49
  widget.updateHoverStates(event);
62
50
  });
@@ -6,7 +6,12 @@ $.fn.linkmapAreaRedraw = function(options) {
6
6
  var mask = options.masks && options.masks.findByPermaId(area.attr('data-mask-id'));
7
7
  area.data('mask', mask || null);
8
8
 
9
- var canvas = area.find(options.target)[0];
9
+ var canvas = area.find('canvas').filter(options.target)[0];
10
+
11
+ if (!canvas) {
12
+ return;
13
+ }
14
+
10
15
  var context = canvas.getContext('2d');
11
16
 
12
17
  if (options.image) {
@@ -63,21 +63,35 @@ pageflow.linkmapPage.ColorMap = (function() {
63
63
  var componentsByKey = {};
64
64
  var components = [];
65
65
 
66
+ var currentStreakKey, currentStreakLength;
67
+
66
68
  for (var y = 0; y < height; y++) {
69
+ currentStreakKey = null;
70
+ currentStreakLength = 0;
71
+
67
72
  for (var x = 0; x < width; x++) {
68
73
  i = (y * width + x) * 4;
69
74
 
70
- if (data[i + 3] > 0) {
75
+ if (!blackOrTransparent(data, i)) {
71
76
  key = [data[i], data[i + 1], data[i + 2]].join('-');
72
77
  component = componentsByKey[key];
73
78
 
79
+ if (currentStreakKey === key && sameColorAboveAndBelow(data, i, width)) {
80
+ currentStreakLength += 1;
81
+ }
82
+ else {
83
+ currentStreakKey = key;
84
+ currentStreakLength = 1;
85
+ }
86
+
74
87
  if (!component) {
75
88
  component = componentsByKey[key] = {
76
89
  color: [data[i], data[i + 1], data[i + 2]],
77
90
  left: x,
78
91
  top: y,
79
92
  right: x + 1,
80
- bottom: y + 1
93
+ bottom: y + 1,
94
+ longestStreak: currentStreakLength
81
95
  };
82
96
 
83
97
  components.push(component);
@@ -87,13 +101,18 @@ pageflow.linkmapPage.ColorMap = (function() {
87
101
  component.top = Math.min(component.top, y);
88
102
  component.right = Math.max(component.right, x + 1);
89
103
  component.bottom = Math.max(component.bottom, y + 1);
104
+ component.longestStreak = Math.max(component.longestStreak, currentStreakLength);
90
105
  }
91
106
  }
92
107
  }
93
108
  }
94
109
 
95
- if (components.length > 20) {
96
- throw tooManyComponentsError();
110
+ components = _(components).select(function(component) {
111
+ return component.longestStreak > 7;
112
+ });
113
+
114
+ if (components.length === 0) {
115
+ throw noComponentsError();
97
116
  }
98
117
 
99
118
  return new ColorMap(width, height, _(components).map(function(component) {
@@ -111,9 +130,30 @@ pageflow.linkmapPage.ColorMap = (function() {
111
130
  }));
112
131
  };
113
132
 
114
- function tooManyComponentsError() {
115
- var error = new Error('Too many color components.');
116
- error.i18nKey = 'pageflow.linkmap_page.color_map.too_many_components';
133
+ function blackOrTransparent(data, i) {
134
+ return (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 0) ||
135
+ data[i + 3] === 0;
136
+ }
137
+ function sameColorAboveAndBelow(data, i, width) {
138
+ var above = i - width * 4;
139
+ var below = i + width * 4;
140
+
141
+ return above >= 0 &&
142
+ below < data.length &&
143
+ sameColor(data, i, above) &&
144
+ sameColor(data, i, below);
145
+ }
146
+
147
+ function sameColor(data, i, j) {
148
+ return data[i] === data[j] &&
149
+ data[i + 1] === data[j + 1] &&
150
+ data[i + 2] === data[j + 2] &&
151
+ data[i + 3] === data[j + 3];
152
+ }
153
+
154
+ function noComponentsError() {
155
+ var error = new Error('No big enough components detected.');
156
+ error.i18nKey = 'pageflow.linkmap_page.errors.no_big_enough_color_map_components';
117
157
 
118
158
  return error;
119
159
  }
@@ -27,6 +27,9 @@ pageflow.linkmapPage.ImageData = (function() {
27
27
 
28
28
  data[i + 3] = 0;
29
29
  }
30
+ else {
31
+ data[i + 3] = 255;
32
+ }
30
33
  }
31
34
 
32
35
  destinationContext.putImageData(imageData, destinationX, destinationY);
@@ -42,10 +45,23 @@ pageflow.linkmapPage.ImageData = (function() {
42
45
  };
43
46
 
44
47
  this.toDataURL = function() {
45
- return canvas.toDataURL();
48
+ var result = canvas.toDataURL();
49
+
50
+ if (!result.match(/^data:image/)) {
51
+ throw new invalidImageDataUrl();
52
+ }
53
+
54
+ return result;
46
55
  };
47
56
  }
48
57
 
58
+ function invalidImageDataUrl() {
59
+ var error = new Error('Invalid data url from canvas.');
60
+ error.i18nKey = 'pageflow.linkmap_page.errors.invalid_image_data';
61
+
62
+ return error;
63
+ }
64
+
49
65
  ImageData.load = function(url) {
50
66
  return pageflow.linkmapPage.RemoteImage.load(url).then(function(image) {
51
67
  var imageData = new ImageData(image.width(), image.height());
@@ -1,38 +1,54 @@
1
- pageflow.linkmapPage.RemoteImage = function(url, image) {
2
- this.width = function() {
3
- return image.width;
4
- };
1
+ pageflow.linkmapPage.RemoteImage = (function() {
2
+ function RemoteImage(url, image) {
3
+ this.width = function() {
4
+ return image.width;
5
+ };
5
6
 
6
- this.height = function() {
7
- return image.height;
8
- };
7
+ this.height = function() {
8
+ return image.height;
9
+ };
10
+
11
+ this.draw = function(canvas, options) {
12
+ options = options || {};
13
+ var context = canvas.getContext('2d');
14
+
15
+ if (options.disableImageSmoothing) {
16
+ context.imageSmoothingEnabled = false;
17
+ }
18
+
19
+ context.drawImage(image,
20
+ 0,
21
+ 0,
22
+ canvas.width,
23
+ canvas.height);
24
+ };
25
+ }
26
+
27
+ RemoteImage.load = function(url) {
28
+ return new $.Deferred(function(deferred) {
29
+ var image = new Image();
9
30
 
10
- this.draw = function(canvas, options) {
11
- options = options || {};
12
- var context = canvas.getContext('2d');
31
+ image.onload = onLoad;
32
+ image.onerror = onError;
33
+ image.crossOrigin = 'Anonymous';
34
+ image.src = url;
13
35
 
14
- if (options.disableImageSmoothing) {
15
- context.imageSmoothingEnabled = false;
16
- }
36
+ function onLoad() {
37
+ deferred.resolve(new pageflow.linkmapPage.RemoteImage(url, image));
38
+ }
17
39
 
18
- context.drawImage(image,
19
- 0,
20
- 0,
21
- canvas.width,
22
- canvas.height);
40
+ function onError() {
41
+ deferred.reject(loadError(url));
42
+ }
43
+ }).promise();
23
44
  };
24
- };
25
45
 
26
- pageflow.linkmapPage.RemoteImage.load = function(url) {
27
- return new $.Deferred(function(deferred) {
28
- var image = new Image();
46
+ return RemoteImage;
29
47
 
30
- image.onload = onLoad;
31
- image.crossOrigin = 'Anonymous';
32
- image.src = url;
48
+ function loadError(url) {
49
+ var error = new Error('Error while loading ' + url + '.');
50
+ error.i18nKey = 'pageflow.linkmap_page.errors.loading_remote_image_failed';
33
51
 
34
- function onLoad() {
35
- deferred.resolve(new pageflow.linkmapPage.RemoteImage(url, image));
36
- }
37
- }).promise();
38
- };
52
+ return error;
53
+ }
54
+ }());
@@ -22,6 +22,10 @@
22
22
  this.overlayTitle = pageElement.find('.description_overlay .link_title');
23
23
  this.overlayDescription = pageElement.find('.description_overlay .link_description');
24
24
 
25
+ this.touchIndicator = pageElement.find('.touch_indicator');
26
+ this.externalLinkLoadingIndicator = pageElement.find('.external_link_loading_indicator');
27
+ this.globalIndicators = this.touchIndicator.add(this.externalLinkLoadingIndicator);
28
+
25
29
  this.startScrollPosition = _.clone(this.options.startScrollPosition);
26
30
 
27
31
  this.currentScrollPosition = null;
@@ -48,6 +52,7 @@
48
52
  pageElement.on('click linkmapbackgroundclick', function() {
49
53
  that.overlayBox.removeClass('active');
50
54
  that.activeAreas.removeClass('hover hover_mobile');
55
+ that.globalIndicators.hide();
51
56
  });
52
57
 
53
58
  $('body').on('linkmaparealeave', '.hover_area', function() {
@@ -61,8 +66,8 @@
61
66
  that.activeAreas.each(function() {
62
67
  var area = $(this);
63
68
 
64
- if (pageflow.browser.has('mobile platform')) {
65
- area.on('linkmapareatouchstart', function(e) {
69
+ area.on('linkmapareaclick', function(event) {
70
+ if (pageflow.browser.has('mobile platform')) {
66
71
  if (area.hasClass('hover_mobile')) {
67
72
  that.activeAreas.removeClass('active');
68
73
  area.addClass('active');
@@ -72,16 +77,23 @@
72
77
  area.addClass('hover hover_mobile');
73
78
 
74
79
  positionOverlay($(this));
80
+
81
+ if (!area.hasClass('dynamic_marker')) {
82
+ displayTouchIndicator(event.originalEvent);
83
+ }
84
+
75
85
  return false;
76
86
  }
77
- });
78
- }
79
- else {
80
- area.on('linkmapareaclick', function(e) {
87
+ }
88
+ else {
81
89
  that.activeAreas.removeClass('active');
82
90
  area.addClass('active');
83
- });
84
- }
91
+ }
92
+
93
+ if (!area.hasClass('dynamic_marker') && area.hasClass('external_site_area')) {
94
+ displayExternalLinkLoadingIndicator(event.originalEvent);
95
+ }
96
+ });
85
97
  });
86
98
 
87
99
  var positionOverlay = function(area) {
@@ -154,7 +166,35 @@
154
166
  that.overlayInnerBox.css('top', '0px');
155
167
  }
156
168
  }
157
- }
169
+ };
170
+
171
+ var displayExternalLinkLoadingIndicator = function(event) {
172
+ positionGlobalIndicator(that.externalLinkLoadingIndicator, event);
173
+ that.externalLinkLoadingIndicator.show();
174
+ };
175
+
176
+ var displayTouchIndicator = function(event) {
177
+ positionGlobalIndicator(that.touchIndicator, event);
178
+ animateTouchIndicator();
179
+ };
180
+
181
+ var animateTouchIndicator = function() {
182
+ that.touchIndicator.hide();
183
+
184
+ setTimeout(function() {
185
+ that.touchIndicator.show();
186
+ }, 500);
187
+ };
188
+
189
+ var positionGlobalIndicator = function(indicator, event) {
190
+ var parentClientRect = that.panoramaWrapper[0].getBoundingClientRect();
191
+ var touch = event.touches ? event.touches[0] : event;
192
+
193
+ indicator.css({
194
+ left: touch.clientX - parentClientRect.left,
195
+ top: touch.clientY - parentClientRect.top
196
+ });
197
+ };
158
198
 
159
199
  this.refresh();
160
200
  },
@@ -1,5 +1,5 @@
1
1
  pageflow.linkmapPage.getPanoramaSize = (function() {
2
- var MIN_SCALING_SIZE = 80;
2
+ var MIN_SCALING_SIZE = 30;
3
3
  var ENVIRONMENT_MARGIN = 1.2;
4
4
 
5
5
  return function getPanoramaSize(options) {
@@ -220,44 +220,46 @@
220
220
  }
221
221
  }
222
222
 
223
- .external_site_area {
223
+ .external_link_loading_indicator,
224
+ .external_site_area .inline_loading_spinner {
225
+ position: absolute;
226
+ height: 100%;
227
+ width: 50%;
228
+ top: 0;
229
+ left: 0;
230
+ overflow: hidden;
224
231
 
225
- .inline_loading_spinner {
232
+ .circle_inner {
226
233
  position: absolute;
227
234
  height: 100%;
228
- width: 50%;
235
+ width: 100%;
229
236
  top: 0;
230
237
  left: 0;
231
238
  overflow: hidden;
239
+ @include transform(rotate(0));
232
240
 
233
- .circle_inner {
241
+ .circle_innerst {
234
242
  position: absolute;
235
243
  height: 100%;
236
- width: 100%;
244
+ width: 200%;
237
245
  top: 0;
238
246
  left: 0;
239
- overflow: hidden;
240
- @include transform(rotate(0));
241
-
242
- .circle_innerst {
243
- position: absolute;
244
- height: 100%;
245
- width: 200%;
246
- top: 0;
247
- left: 0;
248
- border: 3px solid green;
249
- box-sizing: border-box;
250
- border-radius: 50%;
251
- }
247
+ box-sizing: border-box;
248
+ border-radius: 50%;
252
249
  }
253
-
254
- @include inline-loading-spinner;
255
250
  }
256
251
 
257
- &.active.target_self {
258
- .inline_loading_spinner {
259
- display: block;
260
- }
261
- }
252
+ @include inline-loading-spinner;
253
+ }
254
+
255
+ .external_site_area.active.target_self.dynamic_marker .inline_loading_spinner {
256
+ display: block;
257
+ }
258
+
259
+ .external_link_loading_indicator {
260
+ height: 150px;
261
+ width: 75px;
262
+ margin-top: -75px;
263
+ z-index: 2;
262
264
  }
263
265
  }
@@ -1,5 +1,25 @@
1
1
  @include pageflow-page-type-pictograms("linkmap_page");
2
2
 
3
+ @include keyframes(linkmap_touch_indicator_animation) {
4
+ 0% {
5
+ @include transform(translate(-50%, -50%) scale(1));
6
+ opacity: 1;
7
+ }
8
+
9
+ 25% {
10
+ @include transform(translate(-50%, -50%) scale(1.3));
11
+ }
12
+
13
+ 50% {
14
+ @include transform(translate(-50%, -50%) scale(1));
15
+ opacity: 1;
16
+ }
17
+
18
+ 100% {
19
+ opacity: 0;
20
+ }
21
+ }
22
+
3
23
  .linkmap_page {
4
24
  $linkmap-icon-font: "FontAwesome" !default;
5
25
  $linkmap-icon-line-height: 1.1em !default;
@@ -19,38 +39,46 @@
19
39
  $linkmap-audio-progress-color: $linkmap-main-color !default;
20
40
  $linkmap-audio-current-time-color: $linkmap-overlay-text-color !default;
21
41
 
22
- .hover_area.page_area, .hover_area.external_site_area {
23
- .linkmap_marker {
24
- &:before {
25
- content: $linkmap-marker-icon;
26
- font-family: $linkmap-icon-font;
27
- color: white;
28
- font-size: 30px;
29
- background-color: rgba(255, 255, 255, 0.3);
30
- padding: 10px;
31
- border-radius: 50%;
32
- width: 35px;
33
- height: 35px;
34
- @include transform(translate(-50%,-50%));
35
- left: 50%;
36
- top: 50%;
37
- position: absolute;
38
- text-align: center;
39
- opacity: 0;
40
- line-height: $linkmap-icon-line-height;
41
- @include transition(0.5s);
42
- }
43
- }
42
+ .hover_area.page_area .linkmap_marker:before,
43
+ .hover_area.external_site_area .linkmap_marker:before,
44
+ .touch_indicator:before {
45
+ content: $linkmap-marker-icon;
46
+ font-family: $linkmap-icon-font;
47
+ color: white;
48
+ font-size: 30px;
49
+ background-color: rgba(255, 255, 255, 0.3);
50
+ padding: 10px;
51
+ border-radius: 50%;
52
+ width: 35px;
53
+ height: 35px;
54
+ @include transform(translate(-50%,-50%));
55
+ left: 50%;
56
+ top: 50%;
57
+ position: absolute;
58
+ text-align: center;
59
+ opacity: 0;
60
+ line-height: $linkmap-icon-line-height;
61
+ @include transition(0.5s);
62
+ }
44
63
 
45
- &.hover_mobile {
46
- .linkmap_marker {
47
- &:before {
48
- opacity: 1;
49
- background-color: rgba(0,0,0,0.7);
50
- color: $linkmap-icon-color;
51
- }
52
- }
53
- }
64
+ .hover_area.page_area.hover_mobile.dynamic_marker .linkmap_marker:before,
65
+ .hover_area.external_site_area.hover_mobile.dynamic_marker .linkmap_marker:before,
66
+ .touch_indicator:before {
67
+ opacity: 1;
68
+ background-color: rgba(0,0,0,0.7);
69
+ color: $linkmap-icon-color;
70
+ }
71
+
72
+ .touch_indicator {
73
+ display: none;
74
+ position: absolute;
75
+ z-index: 2;
76
+ opacity: 0;
77
+ @include animation(linkmap_touch_indicator_animation 1s);
78
+ }
79
+
80
+ .external_link_loading_indicator .circle_innerst {
81
+ border: 4px solid $linkmap-audio-progress-color;
54
82
  }
55
83
 
56
84
  .linkmap_audio_player_controls {
@@ -8,7 +8,7 @@ module Pageflow
8
8
  visited_image_file = Pageflow::ImageFile.find_by_id(configuration['visited_image_id'])
9
9
 
10
10
  mask_sprite_url_template = MaskSprite.new(id: 1, attachment_file_name: 'data').attachment.url
11
- .gsub(%r'(\d{3}/)+', ':id_partition/')
11
+ .gsub(%r'/(\d{3}/)+', '/:id_partition/')
12
12
 
13
13
  render('pageflow/linkmap_page/areas/div',
14
14
  entry: entry,
@@ -37,6 +37,12 @@
37
37
  <div class="link_description"></div>
38
38
  </div>
39
39
  </div>
40
+ <div class="touch_indicator"></div>
41
+ <div class="external_link_loading_indicator">
42
+ <div class="circle_inner">
43
+ <div class="circle_innerst"></div>
44
+ </div>
45
+ </div>
40
46
  </div>
41
47
  </div>
42
48
  </div>
@@ -23,8 +23,6 @@ de:
23
23
  text_only: Nur Text
24
24
  pageflow:
25
25
  linkmap_page:
26
- color_map:
27
- too_many_components: Das ausgewählte Bild enthält zu viele verschiedene Farbtöne. Es können maximal 20 Bereiche durch das Maskenbild bestimmt werden. Stellen Sie sicher, dass bei der Erstellung des Maskenbildes keine Kantenglättung verwendet wurde, da dies die Zahl der im Bild auftretenden Farbtöne stark erhöhen kann.
28
26
  default_page_transition: "(Standard)"
29
27
  editor:
30
28
  area_types:
@@ -38,11 +36,9 @@ de:
38
36
  destroy: Löschen
39
37
  embedded:
40
38
  area_item:
41
- edit: DELETE
42
39
  hide_marker: Linkmarkierung deaktivieren
43
40
  set_mask: Maske auswählen
44
41
  show_marker: Linkmarkierung aktivieren
45
- toggle_marker: DELETE
46
42
  unset_mask: Frei positionierbar machen
47
43
  file_area_item:
48
44
  edit: Bearbeiten
@@ -74,6 +70,12 @@ de:
74
70
  drag_hint: Wähle einen Bereich für den Hotspot durch Klicken und Ziehen mit der Maus.
75
71
  select_mask_hint: Klicke auf einen der farbigen Bereiche des Masken-Bildes, um einen Bereich für den Hotspot auszuwählen.
76
72
  select_mask_or_drag_hint: Klicke auf einen der farbigen Bereiche des Masken-Bildes oder wähle einen frei positionierten Bereich durch Klicken und Ziehen mit der Maus.
73
+ errors:
74
+ invalid_image_data: Bei der Erkennung der Farbbereiche im Maskenbild ist ein Fehler aufgetreten. Stellen Sie sicher, dass die farbigen Bereiche im Maskenbild begrenzt und alle anderen Teile des Bildes transparent sind.
75
+ loading_remote_image_failed: Beim Laden des Bildes ist ein Fehler aufgetreten.
76
+ mask_image_failed: Beim Verarbeiten des Maskenbildes ist ein Fehler aufgetreten.
77
+ no_big_enough_color_map_components: Es konnten keine Farb-Bereiche erkannt werden. Stellen Sie sicher, dass die Bereiche midestens 7x7 Pixel groß sind.
78
+ saving_mask_image_failed: Beim Speichern des Maskenbildes ist ein Fehler aufgetreten.
77
79
  help_entries:
78
80
  page_type:
79
81
  menu_item: Hotspots
@@ -23,8 +23,6 @@ en:
23
23
  text_only: Text only
24
24
  pageflow:
25
25
  linkmap_page:
26
- color_map:
27
- too_many_components: The selected image contains too many different color values. There is a maximal number of 20 areas that can be determined via the mask image. Make sure that anti aliasing was turned off while creating the mask image. Anti aliasing leads to color gradients inside the image which prevent usage as mask image.
28
26
  default_page_transition: "(Default)"
29
27
  editor:
30
28
  area_types:
@@ -38,11 +36,9 @@ en:
38
36
  destroy: Delete
39
37
  embedded:
40
38
  area_item:
41
- edit: DELETE
42
39
  hide_marker: Hide marker
43
40
  set_mask: Select mask
44
41
  show_marker: Show marker
45
- toggle_marker: DELETE
46
42
  unset_mask: Detach from mask
47
43
  file_area_item:
48
44
  edit: Edit
@@ -74,6 +70,12 @@ en:
74
70
  drag_hint: Select the hotspot's dimension by clicking and dragging somewhere inside the panorama.
75
71
  select_mask_hint: Click on one of the colored areas of the mask image to determine the hotspots shape and position.
76
72
  select_mask_or_drag_hint: Click on one of the colored areas of the mask image or select the hotspot's dimensions by clicking and dragging somewhere inside the panorama.
73
+ errors:
74
+ invalid_image_data: There has been an error while identifying color components. Ensure color areas are bounded inside the image and all other parts of the image are transparent.
75
+ loading_remote_image_failed: Error while loading the image.
76
+ mask_image_failed: There was an error while processing the mask image.
77
+ no_big_enough_color_map_components: No color components identified. Ensure each component is at least 7x7 pixels big.
78
+ saving_mask_image_failed: There has been an error while saving the mask image.
77
79
  help_entries:
78
80
  page_type:
79
81
  menu_item: Hotspots
@@ -1,5 +1,5 @@
1
1
  module Pageflow
2
2
  module LinkmapPage
3
- VERSION = '1.0.0'.freeze
3
+ VERSION = '1.1.0'.freeze
4
4
  end
5
5
  end
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_runtime_dependency 'pageflow', ['>= 0.10', '< 13']
22
22
  spec.add_runtime_dependency 'pageflow-external-links', ['>= 0.3', '< 2']
23
23
 
24
+ spec.add_development_dependency 'pageflow-support', '~> 12.0'
24
25
  spec.add_development_dependency 'bundler', '~> 1.0'
25
26
  spec.add_development_dependency 'rake', '~> 12.0'
26
27
  spec.add_development_dependency 'rspec-rails', '~> 3.0'
@@ -15,7 +15,7 @@ module Pageflow
15
15
 
16
16
  it 'responds with success for member' do
17
17
  user = create(:user)
18
- entry = create(:entry, with_member: user)
18
+ entry = create(:entry, with_editor: user)
19
19
  image_file = create(:image_file, used_in: entry.draft)
20
20
 
21
21
  sign_in(user)
@@ -29,7 +29,7 @@ module Pageflow
29
29
 
30
30
  it 'includes id of created mask sprite in response' do
31
31
  user = create(:user)
32
- entry = create(:entry, with_member: user)
32
+ entry = create(:entry, with_editor: user)
33
33
  image_file = create(:image_file, used_in: entry.draft)
34
34
 
35
35
  sign_in(user)
@@ -45,7 +45,7 @@ module Pageflow
45
45
 
46
46
  it 'creates mask sprite for image' do
47
47
  user = create(:user)
48
- entry = create(:entry, with_member: user)
48
+ entry = create(:entry, with_editor: user)
49
49
  image_file = create(:image_file, used_in: entry.draft)
50
50
 
51
51
  sign_in(user)
@@ -61,7 +61,7 @@ module Pageflow
61
61
 
62
62
  it 'does not recreate mask sprite if it already exists' do
63
63
  user = create(:user)
64
- entry = create(:entry, with_member: user)
64
+ entry = create(:entry, with_editor: user)
65
65
  image_file = create(:image_file, used_in: entry.draft)
66
66
 
67
67
  sign_in(user)
@@ -51,6 +51,16 @@ module Pageflow
51
51
 
52
52
  expect(html).not_to have_selector('a[data-mask-id]')
53
53
  end
54
+
55
+ it 'renders attribute with url template for mask sprite' do
56
+ entry = create(:entry)
57
+ configuration = {}
58
+
59
+ html = helper.linkmap_areas_div(entry, configuration)
60
+
61
+ url_matcher = 'attachments/:id_partition/original'
62
+ expect(html).to have_selector("div[data-mask-sprite-url-template*='#{url_matcher}']")
63
+ end
54
64
  end
55
65
 
56
66
  describe '#linkmap_area' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pageflow-linkmap-page
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Codevise Solutions Ltd.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-11 00:00:00.000000000 Z
11
+ date: 2017-10-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pageflow
@@ -50,6 +50,20 @@ dependencies:
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
52
  version: '2'
53
+ - !ruby/object:Gem::Dependency
54
+ name: pageflow-support
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '12.0'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '12.0'
53
67
  - !ruby/object:Gem::Dependency
54
68
  name: bundler
55
69
  requirement: !ruby/object:Gem::Requirement