pageflow-linkmap-page 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.jshintignore +1 -0
  4. data/.jshintrc +23 -0
  5. data/CHANGELOG.md +8 -0
  6. data/Gemfile +18 -0
  7. data/README.md +62 -0
  8. data/Rakefile +11 -0
  9. data/app/assets/images/pageflow/linkmap_page/text_only_area_type_pictogram.png +0 -0
  10. data/app/assets/images/pageflow/linkmap_page/themes/default/pictograms/sprite.png +0 -0
  11. data/app/assets/images/pageflow/linkmap_page/themes/default/pictograms/wide.png +0 -0
  12. data/app/assets/images/pageflow/linkmap_page_pictogram.png +0 -0
  13. data/app/assets/images/pageflow/linkmap_page_pictogram_small.png +0 -0
  14. data/app/assets/javascript/pageflow/linkmap_page.js +9 -0
  15. data/app/assets/javascript/pageflow/linkmap_page/editor.js +25 -0
  16. data/app/assets/javascript/pageflow/linkmap_page/editor/collections/areas_collection.js +57 -0
  17. data/app/assets/javascript/pageflow/linkmap_page/editor/collections/page_links_collection.js +29 -0
  18. data/app/assets/javascript/pageflow/linkmap_page/editor/config.js +51 -0
  19. data/app/assets/javascript/pageflow/linkmap_page/editor/controllers/side_bar_controller.js +15 -0
  20. data/app/assets/javascript/pageflow/linkmap_page/editor/models/area.js +79 -0
  21. data/app/assets/javascript/pageflow/linkmap_page/editor/models/area_file_selection_handler.js +12 -0
  22. data/app/assets/javascript/pageflow/linkmap_page/editor/models/audio_file_area_type.js +17 -0
  23. data/app/assets/javascript/pageflow/linkmap_page/editor/models/external_link_area_type.js +19 -0
  24. data/app/assets/javascript/pageflow/linkmap_page/editor/models/new_area_file_selection_handler.js +11 -0
  25. data/app/assets/javascript/pageflow/linkmap_page/editor/models/page_configuration_mixin.js +33 -0
  26. data/app/assets/javascript/pageflow/linkmap_page/editor/models/page_link_area_type.js +29 -0
  27. data/app/assets/javascript/pageflow/linkmap_page/editor/models/text_only_area_type.js +15 -0
  28. data/app/assets/javascript/pageflow/linkmap_page/editor/routers/side_bar_router.js +5 -0
  29. data/app/assets/javascript/pageflow/linkmap_page/editor/templates/edit_area.jst.ejs +3 -0
  30. data/app/assets/javascript/pageflow/linkmap_page/editor/templates/embedded/area_item.jst.ejs +11 -0
  31. data/app/assets/javascript/pageflow/linkmap_page/editor/views/areas_list_view.js +44 -0
  32. data/app/assets/javascript/pageflow/linkmap_page/editor/views/configuration_editor_view.js +90 -0
  33. data/app/assets/javascript/pageflow/linkmap_page/editor/views/edit_area_view.js +103 -0
  34. data/app/assets/javascript/pageflow/linkmap_page/editor/views/editable_areas_mode_view.js +10 -0
  35. data/app/assets/javascript/pageflow/linkmap_page/editor/views/embedded/area_item_embedded_view.js +190 -0
  36. data/app/assets/javascript/pageflow/linkmap_page/editor/views/embedded/areas_embedded_view.js +26 -0
  37. data/app/assets/javascript/pageflow/linkmap_page/editor/views/embedded/panorama_embedded_view.js +14 -0
  38. data/app/assets/javascript/pageflow/linkmap_page/features.js +9 -0
  39. data/app/assets/javascript/pageflow/linkmap_page/page_type.js +302 -0
  40. data/app/assets/javascript/pageflow/linkmap_page/vendor/gyro.js +3 -0
  41. data/app/assets/javascript/pageflow/linkmap_page/widgets/hover_video.js +77 -0
  42. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap.js +112 -0
  43. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap_audio_player_controls.js +132 -0
  44. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap_audio_players_controller.js +48 -0
  45. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap_lookaround.js +154 -0
  46. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap_lookaround_strategies/target_speed.js +99 -0
  47. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap_panorama.js +421 -0
  48. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap_scroll_indicators.js +17 -0
  49. data/app/assets/stylesheets/pageflow/linkmap_page.css.scss +266 -0
  50. data/app/assets/stylesheets/pageflow/linkmap_page/animations/rotate.css.scss +8 -0
  51. data/app/assets/stylesheets/pageflow/linkmap_page/audio_player_controls.scss +134 -0
  52. data/app/assets/stylesheets/pageflow/linkmap_page/editor.css.scss +122 -0
  53. data/app/assets/stylesheets/pageflow/linkmap_page/editor/areas_list.scss +15 -0
  54. data/app/assets/stylesheets/pageflow/linkmap_page/editor/file_areas.css.scss +70 -0
  55. data/app/assets/stylesheets/pageflow/linkmap_page/editor/resizable.css.scss +80 -0
  56. data/app/assets/stylesheets/pageflow/linkmap_page/themes/default.css.scss +341 -0
  57. data/app/assets/stylesheets/pageflow/linkmap_page/themes/default/scroll_indicators.scss +82 -0
  58. data/app/controllers/pageflow/external_links/sites_controller.rb +40 -0
  59. data/app/helpers/pageflow/linkmap_page/areas_helper.rb +93 -0
  60. data/app/models/pageflow/linkmap_page/site.rb +11 -0
  61. data/app/views/pageflow/linkmap_page/areas/_div.html.erb +33 -0
  62. data/app/views/pageflow/linkmap_page/page.html +51 -0
  63. data/config/locales/de.yml +119 -0
  64. data/config/locales/en.yml +119 -0
  65. data/config/locales/new/inverted.de.yml +10 -0
  66. data/config/locales/new/inverted.en.yml +10 -0
  67. data/config/locales/new/text_only_area_type.de.yml +11 -0
  68. data/config/locales/new/text_only_area_type.en.yml +11 -0
  69. data/config/routes.rb +5 -0
  70. data/config/spring.rb +1 -0
  71. data/exec/rspec +15 -0
  72. data/exec/spring +18 -0
  73. data/lib/pageflow-linkmap-page.rb +13 -0
  74. data/lib/pageflow/linkmap_page/engine.rb +17 -0
  75. data/lib/pageflow/linkmap_page/page_type.rb +19 -0
  76. data/lib/pageflow/linkmap_page/plugin.rb +9 -0
  77. data/lib/pageflow/linkmap_page/version.rb +5 -0
  78. data/pageflow-linkmap-page.gemspec +37 -0
  79. data/spec/helpers/pageflow/linkmap_page/areas_helper_spec.rb +68 -0
  80. data/spec/spec_helper.rb +15 -0
  81. metadata +265 -0
@@ -0,0 +1,12 @@
1
+ pageflow.linkmapPage.AreaFileSelectionHandler = function(options) {
2
+ var page = pageflow.pages.get(options.id);
3
+ var area = page.configuration.linkmapAreas(options.areasPropertyName).at(parseInt(options.areaIndex, 10));
4
+
5
+ this.call = function(file) {
6
+ area.setReference(options.attributeName, file);
7
+ };
8
+
9
+ this.getReferer = function() {
10
+ return '/linkmap_pages/' + options.id + '/areas/' + options.areaIndex;
11
+ };
12
+ };
@@ -0,0 +1,17 @@
1
+ pageflow.linkmapPage.AudioFileAreaType = Backbone.Model.extend({
2
+ defaults: function() {
3
+ return {
4
+ label: I18n.t('pageflow.linkmap_page.editor.area_types.audio_file')
5
+ };
6
+ },
7
+
8
+ initialize: function(attributes, options) {
9
+ this.pageId = options.pageConfiguration.getRoutableId();
10
+ },
11
+
12
+ selected: function() {
13
+ pageflow.editor.selectFile('audio_files', 'linkmapPage.newArea', {
14
+ id: this.pageId
15
+ });
16
+ }
17
+ });
@@ -0,0 +1,19 @@
1
+ pageflow.linkmapPage.ExternalLinkAreaType = Backbone.Model.extend({
2
+ defaults: function() {
3
+ return {
4
+ label: I18n.t('pageflow.linkmap_page.editor.area_types.external_site'),
5
+ };
6
+ },
7
+
8
+ initialize: function(attributes, options) {
9
+ this.areas = options.pageConfiguration.linkmapAreas();
10
+ },
11
+
12
+ selected: function() {
13
+ var areas = this.areas;
14
+
15
+ pageflow.externalLinks.selectSite().then(function(site) {
16
+ areas.addExternalSite(site.get('perma_id'));
17
+ });
18
+ }
19
+ });
@@ -0,0 +1,11 @@
1
+ pageflow.linkmapPage.NewAreaFileSelectionHandler = function(options) {
2
+ var page = pageflow.pages.get(options.id);
3
+
4
+ this.call = function(file) {
5
+ page.configuration.linkmapAreas().addAudioFile(file.id);
6
+ };
7
+
8
+ this.getReferer = function() {
9
+ return '/pages/' + options.id + '/areas';
10
+ };
11
+ };
@@ -0,0 +1,33 @@
1
+ pageflow.linkmapPage.pageConfigurationMixin = {
2
+ linkmapPageLinks: function() {
3
+ this._linkmapPageLinks = this._linkmapPageLinks || new pageflow.linkmapPage.PageLinksCollection({
4
+ areas: this.linkmapAreas()
5
+ });
6
+
7
+ return this._linkmapPageLinks;
8
+ },
9
+
10
+ linkmapAreas: function() {
11
+ var configuration = this;
12
+
13
+ this._linkmapAreas = this._linkmapAreas || create();
14
+ return this._linkmapAreas;
15
+
16
+ function create() {
17
+ var collection = new pageflow.linkmapPage.AreasCollection(
18
+ configuration.get('linkmap_areas'),
19
+ {
20
+ page: configuration.page
21
+ }
22
+ );
23
+
24
+ configuration.listenTo(collection, 'add remove change', function() {
25
+ configuration.set('linkmap_areas', collection.map(function(area) {
26
+ return _.omit(area.attributes, 'highlighted');
27
+ }));
28
+ });
29
+
30
+ return collection;
31
+ }
32
+ }
33
+ };
@@ -0,0 +1,29 @@
1
+ pageflow.linkmapPage.PageLinkAreaType = Backbone.Model.extend({
2
+ defaults: function() {
3
+ return {
4
+ label: I18n.t('pageflow.linkmap_page.editor.area_types.page')
5
+ };
6
+ },
7
+
8
+ initialize: function(attributes, options) {
9
+ this.areas = options.pageConfiguration.linkmapAreas();
10
+
11
+ this.listenTo(this.areas, 'add remove', function() {
12
+ this.updateDisabled();
13
+ });
14
+
15
+ this.updateDisabled();
16
+ },
17
+
18
+ updateDisabled: function() {
19
+ this.set('disabled', !this.areas.canAddLink());
20
+ },
21
+
22
+ selected: function() {
23
+ var areas = this.areas;
24
+
25
+ pageflow.editor.selectPage().then(function(page) {
26
+ areas.addLink(page.get('perma_id'));
27
+ });
28
+ }
29
+ });
@@ -0,0 +1,15 @@
1
+ pageflow.linkmapPage.TextOnlyAreaType = Backbone.Model.extend({
2
+ defaults: function() {
3
+ return {
4
+ label: I18n.t('pageflow.linkmap_page.editor.area_types.text_only')
5
+ };
6
+ },
7
+
8
+ initialize: function(attributes, options) {
9
+ this.pageConfiguration = options.pageConfiguration;
10
+ },
11
+
12
+ selected: function() {
13
+ this.pageConfiguration.linkmapAreas().addTextOnly();
14
+ }
15
+ });
@@ -0,0 +1,5 @@
1
+ pageflow.linkmapPage.SideBarRouter = Backbone.Marionette.AppRouter.extend({
2
+ appRoutes: {
3
+ 'linkmap_pages/:pageId/areas/:index': 'area'
4
+ }
5
+ });
@@ -0,0 +1,3 @@
1
+ <a class="back"><%= I18n.t('pageflow.linkmap_page.editor.templates.edit_area.back') %></a>
2
+ <a class="destroy"><%= I18n.t('pageflow.linkmap_page.editor.templates.edit_area.destroy') %></a>
3
+ <div class="form_container"></div>
@@ -0,0 +1,11 @@
1
+ <div class="background_image visited_image" data-style-group="panorama"></div>
2
+ <div class="background_image hover_image" data-style-group="panorama"></div>
3
+ <div class="linkmap_marker"></div>
4
+ <span class="area_type_pictogram"></span>
5
+ <div class="linkmap_description">
6
+ <div class="link_title"></div>
7
+ <div class="link_description"></div>
8
+ </div>
9
+ <a class="toggle_marker" href="" title="<%= I18n.t('pageflow.linkmap_page.editor.templates.embedded.area_item.toggle_marker') %>">
10
+ <a class="edit" href="" title="<%= I18n.t('pageflow.linkmap_page.editor.templates.embedded.area_item.edit') %>">
11
+ </a>
@@ -0,0 +1,44 @@
1
+ pageflow.linkmapPage.AreasListView = Backbone.Marionette.View.extend({
2
+ className: 'linkmap_page_areas_list',
3
+
4
+ render: function() {
5
+ this.appendSubview(new pageflow.ListView({
6
+ label: I18n.t('pageflow.linkmap_page.editor.views.areas_list.label'),
7
+ collection: this.model.linkmapAreas(),
8
+ highlight: true,
9
+
10
+ onEdit: function(model) {
11
+ pageflow.editor.navigate(model.editPath(), {trigger: true});
12
+ },
13
+
14
+ itemDescription: function(area) {
15
+ return area.label();
16
+ },
17
+
18
+ itemTypeName: function(area) {
19
+ return {
20
+ 'audio_file': 'audio',
21
+ 'page': 'internal_links_list',
22
+ 'external_site': 'external_links',
23
+ 'text_only': 'text_only'
24
+ }[area.get('target_type')];
25
+ },
26
+
27
+ itemTypeDescription: function(area) {
28
+ return I18n.t('pageflow.linkmap_page.editor.area_types.' + area.get('target_type'));
29
+ },
30
+
31
+ itemIsInvalid: function(area) {
32
+ return !area.target() && area.get('target_type') !== 'text_only';
33
+ },
34
+ }));
35
+
36
+ this.appendSubview(new pageflow.DropDownButtonView({
37
+ sortable: true,
38
+ label: I18n.t('pageflow.linkmap_page.editor.views.areas_list.add'),
39
+ items: pageflow.linkmapPage.areaTypesFor(this.model)
40
+ }));
41
+
42
+ return this;
43
+ }
44
+ });
@@ -0,0 +1,90 @@
1
+ pageflow.linkmapPage.ConfigurationEditorView = pageflow.ConfigurationEditorView.extend({
2
+ configure: function() {
3
+ this.tab('general', function() {
4
+ this.input('title', pageflow.TextInputView, {required: true});
5
+ });
6
+
7
+ this.tab('files', function() {
8
+ this.input('background_type', pageflow.SelectInputView, {
9
+ values: ['image', 'video', 'hover_video'],
10
+ ensureValueDefined: true
11
+ });
12
+
13
+ this.input('panorama_image_id', pageflow.FileInputView, {
14
+ collection: pageflow.imageFiles,
15
+ positioning: true,
16
+ visibleBinding: 'background_type',
17
+ visible: function(backgroundType) {
18
+ return _(['image', 'hover_video']).contains(backgroundType);
19
+ }
20
+ });
21
+
22
+ this.input('panorama_video_id', pageflow.FileInputView, {
23
+ collection: pageflow.videoFiles,
24
+ positioning: true,
25
+ visibleBinding: 'background_type',
26
+ visibleBindingValue: 'video'
27
+ });
28
+
29
+ this.input('panorama_image_id', pageflow.FileInputView, {
30
+ attributeTranslationKeyPrefixes: ['pageflow.linkmap_page.page_attributes.video_type'],
31
+ collection: pageflow.imageFiles,
32
+ positioning: false,
33
+ visibleBinding: 'background_type',
34
+ visibleBindingValue: 'video'
35
+ });
36
+
37
+ this.input('hover_image_id', pageflow.FileInputView, {
38
+ collection: pageflow.imageFiles,
39
+ positioning: false,
40
+ visibleBinding: 'background_type',
41
+ visible: function(backgroundType) {
42
+ return _(['image', 'video']).contains(backgroundType);
43
+ }
44
+ });
45
+
46
+ this.input('panorama_video_id', pageflow.FileInputView, {
47
+ attributeTranslationKeyPrefixes: ['pageflow.linkmap_page.page_attributes.hover_video_type'],
48
+ collection: pageflow.videoFiles,
49
+ positioning: false,
50
+ visibleBinding: 'background_type',
51
+ visibleBindingValue: 'hover_video'
52
+ });
53
+
54
+ this.input('hover_image_id', pageflow.FileInputView, {
55
+ attributeTranslationKeyPrefixes: ['pageflow.linkmap_page.page_attributes.hover_video_type'],
56
+ collection: pageflow.imageFiles,
57
+ positioning: false,
58
+ visibleBinding: 'background_type',
59
+ visibleBindingValue: 'hover_video'
60
+ });
61
+
62
+ this.input('visited_image_id', pageflow.FileInputView, {
63
+ collection: pageflow.imageFiles,
64
+ positioning: false
65
+ });
66
+
67
+ this.input('thumbnail_image_id', pageflow.FileInputView, {
68
+ collection: pageflow.imageFiles,
69
+ positioning: false
70
+ });
71
+ });
72
+
73
+ this.tab('areas', function() {
74
+ this.view(pageflow.linkmapPage.AreasListView, {
75
+ model: this.model
76
+ });
77
+
78
+ this.view(pageflow.linkmapPage.EditableAreasModeView, {
79
+ model: this.model.page
80
+ });
81
+ });
82
+
83
+ this.tab('options', function() {
84
+ this.group('options', {canPauseAtmo: true});
85
+ this.input('limit_scrolling', pageflow.CheckBoxInputView);
86
+ this.input('add_environment', pageflow.CheckBoxInputView);
87
+ this.input('margin_scrolling_disabled', pageflow.CheckBoxInputView);
88
+ });
89
+ }
90
+ });
@@ -0,0 +1,103 @@
1
+ pageflow.linkmapPage.EditAreaView = Backbone.Marionette.Layout.extend({
2
+ template: 'pageflow/linkmap_page/editor/templates/edit_area',
3
+
4
+ regions: {
5
+ formContainer: '.form_container'
6
+ },
7
+
8
+ ui: {
9
+ backButton: 'a.back'
10
+ },
11
+
12
+ events: {
13
+ 'click a.back': 'goBack',
14
+
15
+ 'click a.destroy': 'destroy'
16
+ },
17
+
18
+ onRender: function() {
19
+ var view = this;
20
+ var area = this.model;
21
+ var areaCollection = this.model.collection;
22
+ var configurationEditor = new pageflow.ConfigurationEditorView({
23
+ model: this.model
24
+ });
25
+
26
+ this.configure(configurationEditor);
27
+
28
+ this.formContainer.show(configurationEditor);
29
+ this.model.set('highlighted', true);
30
+ this.model.collection.page.set('areas_editable', true);
31
+
32
+ this.on('close', function() {
33
+ area.unset('highlighted');
34
+ areaCollection.page.unset('areas_editable');
35
+ });
36
+ },
37
+
38
+ configure: function(configurationEditor) {
39
+ var view = this;
40
+
41
+ configurationEditor.tab('general', function() {
42
+ this.input('name', pageflow.TextInputView);
43
+
44
+ this.input('target_type', pageflow.SelectInputView, {
45
+ values: ['page', 'external_site', 'audio_file', 'text_only'],
46
+ ensureValueDefined: true
47
+ });
48
+
49
+ this.input('target_id', pageflow.PageLinkInputView, {
50
+ visibleBinding: 'target_type',
51
+ visibleBindingValue: 'page'
52
+ });
53
+
54
+ this.input('page_transition', pageflow.SelectInputView, {
55
+ translationKeyPrefix: 'pageflow.page_transitions',
56
+ includeBlank: true,
57
+ blankTranslationKey: 'pageflow.linkmap_page.default_page_transition',
58
+ values: pageflow.pageTransitions.names(),
59
+ visibleBinding: 'target_type',
60
+ visibleBindingValue: 'page'
61
+ });
62
+
63
+ this.input('target_id', pageflow.externalLinks.SiteReferenceInputView, {
64
+ visibleBinding: 'target_type',
65
+ visibleBindingValue: 'external_site'
66
+ });
67
+
68
+ this.input('target_id', pageflow.FileInputView, {
69
+ collection: 'audio_files',
70
+ fileSelectionHandler: 'linkmapPage.area',
71
+ fileSelectionHandlerOptions: {
72
+ areaIndex: view.options.areaIndex,
73
+ },
74
+ visibleBinding: 'target_type',
75
+ visibleBindingValue: 'audio_file'
76
+ });
77
+
78
+ this.input('link_title', pageflow.TextInputView);
79
+ this.input('link_description', pageflow.TextAreaInputView, {size: 'short'});
80
+ });
81
+
82
+ configurationEditor.tab('appearance', function() {
83
+ this.input('marker', pageflow.SelectInputView, {values: pageflow.linkmapPage.toggleMarkerOptions});
84
+ this.input('inverted', pageflow.CheckBoxInputView, {
85
+ visibleBinding: 'target_type',
86
+ visible: function(value) {
87
+ return value !== 'text_only';
88
+ }
89
+ });
90
+ });
91
+ },
92
+
93
+ destroy: function() {
94
+ if (confirm(I18n.t('pageflow.linkmap_page.editor.views.edit_area_view.confirm_destroy'))) {
95
+ this.model.remove();
96
+ this.goBack();
97
+ }
98
+ },
99
+
100
+ goBack: function() {
101
+ pageflow.editor.navigate('/pages/' + this.options.page.id + '/areas', {trigger: true});
102
+ }
103
+ });
@@ -0,0 +1,10 @@
1
+ pageflow.linkmapPage.EditableAreasModeView = Backbone.Marionette.View.extend({
2
+ render: function() {
3
+ this.model.set('areas_editable', true);
4
+ return this;
5
+ },
6
+
7
+ onClose: function() {
8
+ this.model.unset('areas_editable');
9
+ }
10
+ });
@@ -0,0 +1,190 @@
1
+ pageflow.linkmapPage.AreaItemEmbeddedView = Backbone.Marionette.ItemView.extend({
2
+ template: 'pageflow/linkmap_page/editor/templates/embedded/area_item',
3
+
4
+ className: 'hover_area',
5
+
6
+ ui: {
7
+ hoverImage: '.hover_image',
8
+ visitedImage: '.visited_image'
9
+ },
10
+
11
+ events: {
12
+ 'click .edit': function() {
13
+ pageflow.editor.navigate(this.model.editPath(), {trigger: true});
14
+ return false;
15
+ },
16
+
17
+ 'click': function() {
18
+ if (this.$el.is('.editable .hover_area')) {
19
+ return false;
20
+ }
21
+ },
22
+
23
+ 'click .toggle_marker': function() {
24
+ if (this.model.get('marker') === 'dynamic_marker') {
25
+ this.model.set('marker', 'no_marker');
26
+ }
27
+ else {
28
+ this.model.set('marker', 'dynamic_marker');
29
+ }
30
+ }
31
+ },
32
+
33
+ modelEvents: {
34
+ change: 'update'
35
+ },
36
+
37
+ onRender: function() {
38
+ this.setupImageViews();
39
+ this.setupDraggableAndResizable();
40
+ this.setupAudioPlayer();
41
+ this.listenToEditable();
42
+
43
+ this.update();
44
+ },
45
+
46
+ setupImageViews: function() {
47
+ var hoverImageView = new pageflow.BackgroundImageEmbeddedView({
48
+ el: this.ui.hoverImage,
49
+ model: this.options.pageConfiguration,
50
+ propertyName: 'hover_image_id'
51
+ }).render();
52
+
53
+ var visitedImageView = new pageflow.BackgroundImageEmbeddedView({
54
+ el: this.ui.visitedImage,
55
+ model: this.options.pageConfiguration,
56
+ propertyName: 'visited_image_id'
57
+ }).render();
58
+ },
59
+
60
+ setupDraggableAndResizable: function() {
61
+ var that = this;
62
+ var scroller = this.options.container.$('.scroller');
63
+
64
+ this.$el.resizable({
65
+ handles: 'n, e, s, w, ne, se, sw, nw',
66
+
67
+ start: function() {
68
+ that.$el.addClass('hover editing');
69
+ scroller.scroller('disable');
70
+
71
+ },
72
+
73
+ stop: function(event, ui) {
74
+ that.$el.removeClass('hover editing');
75
+ savePositionAndSize();
76
+ scroller.scroller('enable');
77
+ }
78
+ });
79
+
80
+ this.$el.draggable({
81
+ iframeFix: true,
82
+
83
+ start: function() {
84
+ that.$el.addClass('hover editing');
85
+ scroller.scroller('disable');
86
+ },
87
+
88
+ drag: function(event, ui) {
89
+ that.$el.linkmapAreaClip(ui.position);
90
+ },
91
+
92
+ stop: function(event, ui) {
93
+ that.$el.removeClass('hover editing');
94
+ scroller.scroller('enable');
95
+ savePositionAndSize();
96
+ }
97
+ }).css('position', 'absolute');
98
+
99
+ if (!this.options.page.get('areas_editable')) {
100
+ this.$el.resizable('disable');
101
+ this.$el.draggable('disable');
102
+ }
103
+
104
+ function savePositionAndSize() {
105
+ var element = that.$el;
106
+
107
+ that.model.set({
108
+ left: parseInt(element.css('left'), 10) / (element.parent().width() / 100),
109
+ top: parseInt(element.css('top'), 10) / (element.parent().height() / 100),
110
+ width: parseInt(element.css('width'), 10) / (element.parent().width() / 100),
111
+ height: parseInt(element.css('height'), 10) / (element.parent().height() / 100)
112
+ });
113
+ }
114
+ },
115
+
116
+ setupAudioPlayer: function() {
117
+ this.$el.linkmapAudioPlayerControls();
118
+ },
119
+
120
+ listenToEditable: function() {
121
+ this.listenTo(this.options.page, 'change:areas_editable', function(model, editable) {
122
+ if (editable) {
123
+ this.$el.resizable('enable');
124
+ this.$el.draggable('enable');
125
+ }
126
+ else {
127
+ this.$el.resizable('disable');
128
+ this.$el.draggable('disable');
129
+ }
130
+ });
131
+ },
132
+
133
+ update: function() {
134
+ var audioFileId = this.model.get('target_id');
135
+
136
+ this.$el.attr('data-audio-file', audioFileId ? audioFileId + '.' + this.cid : '');
137
+ this.$el.attr('data-target-type', this.model.get('target_type'));
138
+ this.$el.attr('data-target-id', this.model.get('target_id'));
139
+ this.$el.attr('data-page-transition', this.model.get('page_transition'));
140
+
141
+ this.$el.toggleClass('highlighted', !!this.model.get('highlighted'));
142
+
143
+ this.$el.attr('data-width', this.model.get('width'));
144
+ this.$el.attr('data-height', this.model.get('height'));
145
+
146
+ this.$el.css('left', this.model.get('left') + '%');
147
+ this.$el.css('top', this.model.get('top') + '%');
148
+ this.$el.css('width', this.model.get('width') + '%');
149
+ this.$el.css('height', this.model.get('height') + '%');
150
+
151
+ this.$el.toggleClass('portrait', this.$el.width() <= this.$el.height());
152
+ this.$el.toggleClass('landscape', this.$el.width() > this.$el.height());
153
+
154
+ _(['page', 'audio_file', 'external_site', 'text_only']).each(function(type) {
155
+ this.$el.toggleClass(type + '_area', this.model.get('target_type') === type);
156
+ }, this);
157
+
158
+ var linkmapMarker = this.$el.find('.linkmap_marker');
159
+ var margin = 32;
160
+
161
+ if (this.$el.width() <= this.$el.height()) {
162
+ linkmapMarker.css({
163
+ 'width': this.$el.width() - margin,
164
+ 'height': this.$el.width() - margin,
165
+ });
166
+ }
167
+ else {
168
+ linkmapMarker.css({
169
+ 'width': this.$el.height() - margin,
170
+ 'height': this.$el.height() - margin,
171
+ });
172
+ }
173
+
174
+ var marker = this.model.get('marker');
175
+ var element = this.$el;
176
+ var that = this;
177
+
178
+ var linkTitle = this.$el.find('.link_title');
179
+ var linkDescription = this.$el.find('.link_description');
180
+
181
+ linkTitle.html(this.model.get('link_title'));
182
+ linkDescription.html(this.model.get('link_description'));
183
+
184
+ _.forEach(pageflow.linkmapPage.toggleMarkerOptions, function(option) {
185
+ element.toggleClass(option, that.model.get('marker') === option);
186
+ });
187
+
188
+ element.toggleClass('inverted', !!this.model.get('inverted'));
189
+ }
190
+ });