Browse Source

Evolution #169: Interface d'aide: Utilisation de aSimpleTour (plugin jquery) pour mise en place tour de visite

Bastien Sevajol 11 years ago
parent
commit
ba2dffdd81

+ 81 - 1
app/Resources/translations/text.fr.yml View File

@@ -73,4 +73,84 @@ help:
73 73
                       avoir effectué une recherche.
74 74
     title2:           Exemple avec Youtube
75 75
     title3:           Exemple avec Soundcloud
76
-                      
76
+
77
+help_tour:
78
+  buttons:
79
+    next:             Suivant
80
+    prev:             Précédent
81
+    start:            Démarrer
82
+    end:              Ne plus voir
83
+  home:
84
+    welcome:
85
+      tour:           |
86
+                      "<h1>Un petit tour de démonstration ?</h1>"+
87
+                      "<p>Appuyez sur le bouton \"Démarrer\" pour voir une petite "+
88
+                      "démonstration de ce que vous pouvez faire sur Muzi.ch</p>"
89
+    elements:
90
+      tour:           |
91
+                      "<h1>Le flux</h1>"+
92
+                      "<p>L'élément central de Muzi.ch est son flux de partages. "+
93
+                      "C'est ici que l'on retrouve les musiques partagés par les "+
94
+                      "différents utilisateurs.</p>"
95
+      tooltip:        |
96
+                      "<p>Les musiques apparaissent des plus récentes aux plus "+
97
+                      "anciennes.</p>"
98
+    element:
99
+      tour:           |
100
+                      "<h1>Les partages</h1>"+
101
+                      "<p>Différentes actions sont possibles avec les partages ...</p>"
102
+      play:           |
103
+                      "<p>En cliquant sur la miniature vous pouvez lancer la lecture de "+
104
+                      "la musique si le partage "+
105
+                      "est issue d'un site supporté, ou ouvrir la page partagé par "+
106
+                      "l'utilisateur.</p>"
107
+      actions:        |
108
+                      "<p>Vous pouvez, sur chaques partages: "+
109
+                      "<strong>Ouvrir la page d'origine</strong>, "+
110
+                      "<strong>lancer la lecture automatique</strong> (si le lien est supporté), "+
111
+                      "<strong>Proposer des tags</strong>, "+
112
+                      "<strong>re-partager</strong> et "+
113
+                      "<strong>signaler le partage comme innaproprié.</strong> "+
114
+                      "</p>"
115
+      likefav:        |
116
+                      "<p>Si cette musique vous a plu: récompensez l'utilisateur avec un pouce ! "+
117
+                      " Vous pouvez égallement ajouter ce partage a votre liste de musiques favorites.</p>"
118
+    filters:
119
+      tour:           |
120
+                      "<h1>Filtres</h1>"+
121
+                      "<p>Vous pouvez filtrer les partages a l'aide de tags.</p>"
122
+      notags:         |
123
+                      "<p>Sans tags, comme maintenant.</p>"
124
+      withtags:       |
125
+                      "<p>Ou avec tags !</p>"
126
+    
127
+    network:
128
+      tour:           |
129
+                      "<h1>Les réseaux</h1>"+
130
+                      "<p>Vous pouvez aussi filtrer les partages en fonction du réseau.</p>"
131
+      public:         |
132
+                      "<p>Le réseau public (Réseau global), ce sont tous les partages.</p>"
133
+      private:        |
134
+                      "<p>Le réseau personel (Mon réseau) représente les partages effectués par les "+
135
+                      "utilisateurs et les groupes que vous avez décidé de suivre.</p>"
136
+                      
137
+    addelement:
138
+      tour:           |
139
+                      "<h1>Ajouter un partage</h1>"+
140
+                      "<p>Le deuxième point principale de Muzi.ch est l'ajout de partages. "+
141
+                      "Plus votre partage sera apprécié, plus vous gagnerez en réputation "+
142
+                      "et plus vous partagerez avec des tags précis, plus vos partages seront écoutés.</p>"
143
+      url:            |
144
+                      "<p>La première étape sera de saisir l'adresse http:// de la page "+
145
+                      "contenant la musique que vous souhaitez partager.</p>"
146
+      form:           |
147
+                      "<p>Si l'adresse que vous avez saisis représente une ressource sur un site géré "+
148
+                      "par Muzi.ch, des informations préalables vous seront proposés. Sinon "+
149
+                      "il faudra simplement les entrer vous même. <strong>Pensez à saisir "+
150
+                      "des tags pour être précis dans votre partage !</strong></p>"
151
+    end:
152
+      tour:           |
153
+                      "<h1>C'est parti !</h1>"+
154
+                      "<p>Amusez vous bien !</p>"
155
+      go:             |
156
+                      "<p>C'est parti !</p>"

+ 33 - 2
src/Muzich/CoreBundle/Entity/User.php View File

@@ -48,6 +48,8 @@ class User extends BaseUser
48 48
    */
49 49
   const DATA_DIFF_UPDATED        = "data_diff_updated";
50 50
   
51
+  const HELP_TOUR_HOME = "home";
52
+  
51 53
  /**
52 54
   * @ORM\Id
53 55
   * @ORM\Column(type="integer")
@@ -264,8 +266,7 @@ class User extends BaseUser
264 266
     $this->groups = new ArrayCollection();
265 267
     $this->groups_owned = new ArrayCollection();
266 268
     $this->help_tour = json_encode(array(
267
-      'home' => true,
268
-      
269
+      self::HELP_TOUR_HOME => true
269 270
     ));
270 271
     parent::__construct();
271 272
   }
@@ -1030,4 +1031,34 @@ class User extends BaseUser
1030 1031
     return $this->mail_partner;
1031 1032
   }
1032 1033
   
1034
+  public function getHelpTour()
1035
+  {
1036
+    return json_decode($this->help_tour, true);
1037
+}
1038
+  
1039
+  public function setHelpTour($help_tour)
1040
+  {
1041
+    $this->help_tour = json_encode($help_tour);
1042
+  }
1043
+  
1044
+  public function wantSeeHelp($help_id)
1045
+  {
1046
+    $help_tour_status = $this->getHelpTour();
1047
+    if (array_key_exists($help_id, $help_tour_status))
1048
+    {
1049
+      return $help_tour_status[$help_id];
1050
+    }
1051
+    return false;
1052
+  }
1053
+  
1054
+  public function setSeeHelp($help_id, $boolean)
1055
+  {
1056
+    $help_tour_status = $this->getHelpTour();
1057
+    if (array_key_exists($help_id, $help_tour_status))
1058
+    {
1059
+      $help_tour_status[$help_id] = ($boolean)?true:false;
1060
+    }
1061
+    $this->setHelpTour($help_tour_status);
1062
+  }
1063
+  
1033 1064
 }

+ 24 - 0
src/Muzich/CoreBundle/Resources/public/css/main.css View File

@@ -1951,4 +1951,28 @@ a#autoplay_close, a#helpbox_close
1951 1951
 a#helpbox_close
1952 1952
 {
1953 1953
   margin-top: 10px;
1954
+}
1955
+
1956
+div#tourtip, div#tourControls
1957
+{
1958
+  z-index: 999;
1959
+  border: 10px solid #CD0B1A;
1960
+  background: #fff;
1961
+}
1962
+
1963
+div#tourtip
1964
+{
1965
+  width: 450px;
1966
+}
1967
+
1968
+div#tourtip h1, div#tourControls h1
1969
+{
1970
+  font-size: 1.55em;
1971
+  margin-top: 0;
1972
+}
1973
+
1974
+div#tourControls a#tourEnd
1975
+{
1976
+  margin-top: 10px;
1977
+  float: right;
1954 1978
 }

+ 104 - 0
src/Muzich/CoreBundle/Resources/views/HelpTour/home.html.twig View File

@@ -0,0 +1,104 @@
1
+{% autoescape false %}
2
+  <script>
3
+    $(document).ready(function(){ 
4
+      $.aSimpleTour({
5
+        data : [
6
+          { 
7
+            element: '#elements_list', 
8
+            tooltip : {{ 'help_tour.home.elements.tooltip'|trans({}, 'text') }},
9
+            position : 'T',
10
+            text : {{ 'help_tour.home.elements.tour'|trans({}, 'text') }},
11
+            tooltipCallback : function(){ $('#tabs_tag_search_no_tags').trigger('click'); }
12
+          },
13
+          { 
14
+            element: 'ul.elements li:first td.element_thumbnail', 
15
+            text : {{ 'help_tour.home.element.tour'|trans({}, 'text') }},
16
+            tooltip: {{ 'help_tour.home.element.play'|trans({}, 'text') }},
17
+            position : 'R'
18
+          },
19
+          { 
20
+            element: 'ul.elements li:first ul.element_links_actions',
21
+            text : {{ 'help_tour.home.element.tour'|trans({}, 'text') }},
22
+            tooltip: {{ 'help_tour.home.element.actions'|trans({}, 'text') }},
23
+            position : 'L'
24
+          },
25
+          { 
26
+            element: 'ul.elements li:first ul.element_thumb_actions',
27
+            text : {{ 'help_tour.home.element.tour'|trans({}, 'text') }},
28
+            tooltip: {{ 'help_tour.home.element.likefav'|trans({}, 'text') }},
29
+            position : 'R'
30
+          },
31
+          { 
32
+            element: '#tabs_tag_search_no_tags',
33
+            text : {{ 'help_tour.home.filters.tour'|trans({}, 'text') }},
34
+            tooltip: {{ 'help_tour.home.filters.notags'|trans({}, 'text') }},
35
+            position : 'B'
36
+          },
37
+          { 
38
+            element: '#tabs_tag_search_with_tags',
39
+            text : {{ 'help_tour.home.filters.tour'|trans({}, 'text') }},
40
+            tooltip: {{ 'help_tour.home.filters.withtags'|trans({}, 'text') }},
41
+            position : 'T',
42
+            tooltipCallback : function(){ $('#tabs_tag_search_with_tags').trigger('click'); }
43
+          },
44
+          { 
45
+            element: '#header_menu a.all_network',
46
+            text : {{ 'help_tour.home.network.tour'|trans({}, 'text') }},
47
+            tooltip: {{ 'help_tour.home.network.public'|trans({}, 'text') }},
48
+            position : 'B'
49
+          },
50
+          { 
51
+            element: '#link_all_network',
52
+            text : {{ 'help_tour.home.network.tour'|trans({}, 'text') }},
53
+            tooltip: {{ 'help_tour.home.network.private'|trans({}, 'text') }},
54
+            position : 'B'
55
+          },
56
+          { 
57
+            element: '#mainbox',
58
+            text : {{ 'help_tour.home.addelement.tour'|trans({}, 'text') }},
59
+            tooltip: {{ 'help_tour.home.addelement.url'|trans({}, 'text') }},
60
+            position : 'T',
61
+            tooltipCallback : function(){ 
62
+              $('#element_add_link').trigger('click'); 
63
+              $('#element_add_url').val('http://www.jamendo.com/fr/list/a114042/falling-apart');
64
+            }
65
+          },
66
+          { 
67
+            element: '#mainbox',
68
+            text : {{ 'help_tour.home.addelement.tour'|trans({}, 'text') }},
69
+            tooltip: {{ 'help_tour.home.addelement.form'|trans({}, 'text') }},
70
+            position : 'T',
71
+            tooltipCallback : function(){ 
72
+              $('#element_add_url').val('http://www.jamendo.com/fr/list/a114042/falling-apart');
73
+              $('#form_add_first_part input[type="submit"]').trigger('click');
74
+            }
75
+          },
76
+          { 
77
+            element: '#header_logo',
78
+            tooltip : {{ 'help_tour.home.end.go'|trans({}, 'text') }},
79
+            text : {{ 'help_tour.home.end.tour'|trans({}, 'text') }}
80
+          }
81
+        ],
82
+        controlsPosition : 'TR',
83
+        welcomeMessage : {{ 'help_tour.home.welcome.tour'|trans({}, 'text') }},
84
+        tooltipColors:  { 'color' : 'black', 'backgroud' : ''},
85
+        controlsColors: { 'color' : 'black', 'backgroud' : ''},
86
+        buttons : { 
87
+          next:   '{{ 'help_tour.buttons.next'|trans({}, 'text') }}', 
88
+          prev:   '{{ 'help_tour.buttons.prev'|trans({}, 'text') }}', 
89
+          start:  '{{ 'help_tour.buttons.start'|trans({}, 'text') }}', 
90
+          end:    '{{ 'help_tour.buttons.end'|trans({}, 'text') }}' 
91
+        },
92
+        endCallback: function(){ 
93
+          $('#element_add_close_link').trigger('click');
94
+          JQueryJson("{{ path('user_hide_help', {
95
+            'help_id' : 'home',
96
+            'token'   :  app.user.getPersonalHash('updateHelpAction')
97
+          }) }}", {}, $.noop);
98
+        }
99
+      }
100
+
101
+      );
102
+    });
103
+  </script>
104
+{% endautoescape %}

+ 3 - 1
src/Muzich/CoreBundle/Resources/views/Layout/head_js.html.twig View File

@@ -1,6 +1,6 @@
1 1
 {% javascripts
2 2
   'js/jquery-1.8.2.prod.js'
3
-  'js/jquery-ui-1.8.7.min.js'
3
+  'js/jquery-ui-1.10.1.custom.min.js'
4 4
   'js/swfobject.js'
5 5
   'js/soundcloud/api.js'
6 6
   'js/soundcloud/sdk.js'
@@ -8,6 +8,8 @@
8 8
   'jplayer/js/jplayer.playlist.min.js'
9 9
   'js/jquery.form-2.14.js'
10 10
   'js/jConfirmAction/jconfirmaction.jquery.js'
11
+  'js/jquery.scrollTo.min.js'
12
+  'js/jquery.aSimpleTour.js'
11 13
   '@MuzichCoreBundle/Resources/public/js/TagPrompt.js'
12 14
   '@MuzichCoreBundle/Resources/public/js/player/*'
13 15
   '@MuzichCoreBundle/Resources/public/js/play2.js'

+ 2 - 2
src/Muzich/CoreBundle/Resources/views/Menu/main_menu.html.twig View File

@@ -5,13 +5,13 @@
5 5
   {% endif %}
6 6
   
7 7
   <li class="{% if network_public == '1' and not ids_display %}selected{% endif %}">
8
-    <a href="{{ path('home') }}" class="all_network">
8
+    <a id="link_all_network" href="{{ path('home') }}" class="all_network">
9 9
       {{ 'filter.network_all'|trans({}, 'userui') }}
10 10
     </a>
11 11
   </li>
12 12
   <li class="separator"></li>
13 13
   <li class="{% if network_public == '0' and not ids_display %}selected{% endif %}">
14
-    <a href="{{ path('mynetwork_home') }}" class="my_network" >
14
+    <a id="link_my_network" href="{{ path('mynetwork_home') }}" class="my_network" >
15 15
       {{ 'filter.network_my'|trans({}, 'userui') }}
16 16
     </a>
17 17
   </li>

+ 6 - 0
src/Muzich/HomeBundle/Resources/views/Home/index.html.twig View File

@@ -12,6 +12,10 @@
12 12
     'box_title': 'home.add_element_box.title'|trans({}, 'navigationui')
13 13
   } %}
14 14
 
15
+  {% if app.user.wantSeeHelp('home') %}
16
+    {% include 'MuzichCoreBundle:HelpTour:home.html.twig' %}
17
+  {% endif %}
18
+
15 19
   {# TODO: Cette partie de javascript ne devra plus exister après la réecriture du code javascript #}
16 20
   {% if from_url is defined %}
17 21
   {% if from_url %}
@@ -45,12 +49,14 @@
45 49
   
46 50
   </div>
47 51
 
52
+  <div id="elements_list">
48 53
   {% include "MuzichCoreBundle:SearchElement:default.html.twig" with {
49 54
     'noelements_filter'    : true,
50 55
     'display_new_elements' : true,
51 56
     'display_autoplay'     : true,
52 57
     'autoplay_context'     : 'home'
53 58
   }%}
59
+  </div>
54 60
   
55 61
   {% if elements|length %}
56 62
     {% include "MuzichCoreBundle:SearchElement:more_button.html.twig" with {

+ 16 - 0
src/Muzich/UserBundle/Controller/UserController.php View File

@@ -590,4 +590,20 @@ class UserController extends Controller
590 590
     return $this->redirect($this->generateUrl('my_account'));
591 591
   }
592 592
   
593
+  public function updateHelpViewedAction($help_id, $token)
594
+  {
595
+    if ($this->getUser()->getPersonalHash('updateHelpAction') != $token)
596
+    {
597
+      return $this->jsonNotFoundResponse();
598
+    }
599
+    
600
+    $this->getUser()->setSeeHelp($help_id, false);
601
+    $this->persist($this->getUser());
602
+    $this->flush();
603
+    
604
+    return $this->jsonResponse(array(
605
+      'status' => 'success'
606
+    ));
607
+  }
608
+  
593 609
 }

+ 5 - 0
src/Muzich/UserBundle/Resources/config/routing.yml View File

@@ -55,3 +55,8 @@ user_update_preferences:
55 55
   requirements:
56 56
     _method:  POST
57 57
   
58
+user_hide_help:
59
+  pattern: /account/update-help/hide/{help_id}/{token}
60
+  defaults: { _controller: MuzichUserBundle:User:updateHelpViewed }
61
+  requirements:
62
+    _method:  POST

File diff suppressed because it is too large
+ 6 - 0
web/js/jquery-ui-1.10.1.custom.min.js


+ 340 - 0
web/js/jquery.aSimpleTour.js View File

@@ -0,0 +1,340 @@
1
+  /**
2
+ * jQuery aSimpleTour
3
+ *
4
+ * @description Tour web
5
+ * @author alvaro.veliz@gmail.com
6
+ * @servedby perkins (http://p.erkins.com)
7
+ * 
8
+ * Dependencies :
9
+ * - jQuery scrollTo
10
+ * 
11
+ * This idea is based on http://tympanus.net/codrops/2010/12/21/website-tour/ by Manoela Lic (https://twitter.com/#!/crnacura)
12
+ */
13
+
14
+(function( $ ) {
15
+
16
+  var settings = {
17
+    data : [],
18
+    autoStart : false,
19
+    controlsPosition : 'TR',
20
+    welcomeMessage : '<h2>Tour</h2><p>Welcome to the Tour Plugin</p>',
21
+    buttons : {
22
+      next : 'Next',
23
+      prev : 'Previous',
24
+      start : 'Start',
25
+      end : 'End'
26
+    },
27
+    controlsColors : {
28
+      background: 'rgba(8, 68, 142, 0.80)',
29
+      color: '#fff'
30
+    },
31
+    tooltipColors : {
32
+      background: 'rgba(0, 0, 0, 0.70)',
33
+      color: '#fff'
34
+    },
35
+    endCallback: $.noop()
36
+  };
37
+
38
+  var options, step, steps;
39
+  var ew, eh, el, et;
40
+  var started = false;
41
+  var direction = 'f';
42
+
43
+  var $tooltip    = $('<div>',{
44
+                      id         : 'tourtip',
45
+                      className  : 'tourtip',
46
+                      html       : ''
47
+                    }).css({
48
+                      'display'     : 'none',
49
+                      'padding'     : '10px 20px',
50
+                      'position'    : 'absolute',
51
+                      'font-family' : 'sans-serif',
52
+                      'border-radius' : '5px',
53
+                      'font-size'   : '12px',
54
+                      'box-sizing'  : 'border-box'
55
+                    });
56
+
57
+  var methods = {
58
+    init : function( opts ) {
59
+      if (started == false ) {
60
+        started = true;
61
+        options = $.extend(settings, opts);
62
+        
63
+        controls = '<div id="tourControls">\
64
+          <div id="tourText">'+options.welcomeMessage+'</div>\
65
+          <div id="tourButtons">\
66
+            <button id="tourPrev" style="display:none">'+options.buttons.prev+'</button>\
67
+            <button id="tourNext">'+options.buttons.start+'</button>\
68
+            <a href="javascript:void(0);" id="tourEnd" style="display:block;">'+options.buttons.end+'</a>\
69
+          </div>\
70
+        </div>';
71
+        $controlsCss = { 'display' : 'block', 'position': 'fixed', 'width' : '200px', 'padding' : '10px 20px', 'border-radius' : '10px', 'font-family' : 'sans-serif' };
72
+        $controls = $(controls).css($controlsCss).css(options.controlsColors);
73
+        $cpos = methods.getControlPosition(options.controlsPosition);
74
+        $controls.css($cpos);
75
+        $('body').append($controls);
76
+
77
+        $tooltip.css(options.tooltipColors);
78
+
79
+        step = -1;
80
+        steps = options.data.length;
81
+        $('body').prepend($tooltip);  
82
+      }
83
+    },
84
+    next : function() {
85
+      direction = 'f';
86
+      step++;
87
+
88
+      if (step == steps) {
89
+        options.endCallback();
90
+        methods.destroy();
91
+      }
92
+      else {
93
+        $tooltip.hide();
94
+        stepData = options.data[step];
95
+
96
+        if (step <= steps) {
97
+          $('#tourPrev').show();
98
+          $('#tourEnd').show();
99
+          $('#tourNext').show().html(options.buttons.next);
100
+        }
101
+
102
+        methods.setTooltip(stepData);
103
+      }
104
+    },
105
+    prev : function() {
106
+      direction = 'b';
107
+
108
+      $tooltip.hide();
109
+
110
+      if (step < steps) {
111
+        $('#tourNext').show().html(options.buttons.next);
112
+      }
113
+
114
+      if (step <= 0) {
115
+        $('#tourPrev').hide();
116
+        $('#tourEnd').hide();
117
+        $('#tourNext').html(options.buttons.start);
118
+        step--;
119
+      }
120
+      else {
121
+        step--;
122
+        stepData = options.data[step];
123
+
124
+        methods.setTooltip(stepData);
125
+      }
126
+    },
127
+    setTooltip : function(stepData) {
128
+      $element = $(stepData.element);
129
+
130
+      if (stepData.controlsPosition) {
131
+        methods.setControlsPosition(stepData.controlsPosition);
132
+      }
133
+
134
+      if (stepData.tooltip) {
135
+        $tooltip.html(stepData.tooltip);
136
+        text = (typeof stepData.text != 'undefined') ? stepData.text : stepData.tooltip;
137
+        $('#tourText').html(text);
138
+        
139
+        tooltipPos = (typeof stepData.position == 'undefined') ? 'BL' : stepData.position;
140
+        $pos = methods.getTooltipPosition(tooltipPos, $element);
141
+        
142
+        $tooltip.css({ 'top': $pos.top+'px', 'left': $pos.left+'px' });
143
+        $tooltip.show('fast');  
144
+
145
+        $.scrollTo($tooltip, 400, { offset : -100});
146
+      }
147
+      
148
+      if (typeof stepData.tooltipCallback != 'undefined') {
149
+        stepData.tooltipCallback();
150
+      }
151
+
152
+
153
+      if (typeof stepData.callback != 'undefined') {
154
+        if (stepData.callback == 'click') {
155
+          urlRegex = /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/;
156
+          urlslugRegex = /^[a-z0-9-]+$/;
157
+
158
+          if (urlRegex.test($element.attr('href')) || urlslugRegex.test($element.attr('href')) ) {
159
+            location.href = $element.attr('href');
160
+          }
161
+          else {
162
+            $element.trigger('click');  
163
+          }
164
+        }
165
+        else {
166
+          if (typeof eval(stepData.callback) == 'function') {
167
+            eval(stepData.callback);
168
+          }
169
+        }
170
+      }
171
+
172
+      if (stepData.next === true) {
173
+        if (direction == 'f') {
174
+          methods.next();  
175
+        }
176
+        else {
177
+          methods.prev();
178
+        }
179
+      }
180
+
181
+    },
182
+    setControlsPosition : function(pos) {
183
+      chtml = $controls.html();
184
+      $controls.remove();
185
+      $controls = $(controls).html(chtml);
186
+      $controls = $controls.css($controlsCss).css(options.controlsColors);
187
+      position = methods.getControlPosition(pos);
188
+      $controls.css(position);
189
+      $('body').append($controls);
190
+    },
191
+    getTooltipPosition : function(pos, $e) {
192
+      ew = $element.outerWidth();
193
+      eh = $element.outerHeight();
194
+      el = $element.offset().left;
195
+      et = $element.offset().top;
196
+      tw = $tooltip.width() + parseInt($tooltip.css('padding-left')) + parseInt($tooltip.css('padding-right'));
197
+      th = $tooltip.height() + parseInt($tooltip.css('padding-top')) +  + parseInt($tooltip.css('padding-bottom'));
198
+
199
+      $('.tourArrow').remove();
200
+      tbg = $tooltip.css('background-color');
201
+
202
+      $upArrow = $('<div class="tourArrow"></div>').css({ 'position' : 'absolute', 'display' : 'block', 'width' : '0', 'height' : '0', 'border-left' : '5px solid transparent', 'border-right' : '5px solid transparent', 'border-bottom' : '5px solid '+tbg });
203
+      $downArrow = $('<div class="tourArrow"></div>').css({ 'position' : 'absolute', 'display' : 'block', 'width' : '0', 'height' : '0', 'border-left' : '5px solid transparent', 'border-right' : '5px solid transparent', 'border-top' : '5px solid '+tbg });
204
+      $rightArrow = $('<div class="tourArrow"></div>').css({ 'position' : 'absolute', 'display' : 'block', 'width' : '0', 'height' : '0', 'border-top' : '5px solid transparent', 'border-bottom' : '5px solid transparent', 'border-left' : '5px solid '+tbg });
205
+      $leftArrow = $('<div class="tourArrow"></div>').css({ 'position' : 'absolute', 'display' : 'block', 'width' : '0', 'height' : '0', 'border-top' : '5px solid transparent', 'border-bottom' : '5px solid transparent', 'border-right' : '5px solid '+tbg });
206
+      switch (pos) {
207
+        case 'BL' :
208
+          position = { 'left'  : el, 'top' : et + eh + 10 };
209
+          $upArrow.css({ top: '-5px', left: '48%' });
210
+          $tooltip.prepend($upArrow);
211
+          break;
212
+
213
+        case 'BR' :
214
+          position = { 'left'  : el + ew - tw, 'top' : et + eh + 10 };
215
+          $upArrow.css({ top: '-5px', left: '48%' });
216
+          $tooltip.prepend($upArrow);
217
+          break;
218
+
219
+        case 'TL' :
220
+          position = { 'left'  : el, 'top' : (et - th) -10 };
221
+          $downArrow.css({ top: th, left: '48%' });
222
+          $tooltip.append($downArrow);
223
+          break;
224
+
225
+        case 'TR' :
226
+          position = { 'left'  : (el + ew) - tw, 'top' : et - th -10 };
227
+          $downArrow.css({ top: th, left: '48%' });
228
+          $tooltip.append($downArrow);
229
+          break;
230
+
231
+        case 'RT' :
232
+          position = { 'left'  : el + ew + 10, 'top' : et };
233
+          $leftArrow.css({ left: '-5px' });
234
+          $tooltip.prepend($leftArrow);
235
+          break;
236
+
237
+        case 'RB' :
238
+          position = { 'left'  : el + ew + 10, 'top' : et + eh - th };
239
+          $leftArrow.css({ left: '-5px' });
240
+          $tooltip.prepend($leftArrow);
241
+          break;
242
+
243
+        case 'LT' :
244
+          position = { 'left'  : (el - tw) - 10, 'top' : et };
245
+          $rightArrow.css({ right: '-5px' });
246
+          $tooltip.prepend($rightArrow);
247
+          break;
248
+
249
+        case 'LB' :
250
+          position = { 'left'  : (el - tw) - 10, 'top' : et + eh - th};
251
+          $rightArrow.css({ right: '-5px' });
252
+          $tooltip.prepend($rightArrow);
253
+          break;
254
+
255
+        case 'B'  :
256
+          position = { 'left'  : el + ew/2 - tw/2, 'top' : (et + eh) + 10 };
257
+          $upArrow.css({ top: '-5px', left: '48%' });
258
+          $tooltip.prepend($upArrow);
259
+          break;
260
+
261
+        case 'L'  :
262
+          position = { 'left'  : (el - tw) - 10, 'top' : et + eh/2 - th/2 };
263
+          $rightArrow.css({ right: '-5px' });
264
+          $tooltip.prepend($rightArrow);
265
+          break;
266
+
267
+        case 'T'  :
268
+          position = { 'left'  : el + ew/2 - tw/2, 'top' : (et - th) - 10 };
269
+          $downArrow.css({ top: th, left: '48%' });
270
+          $tooltip.append($downArrow);
271
+          break;
272
+
273
+        case 'R'  :
274
+          position = { 'left'  : (el + ew) + 10, 'top' : et + eh/2 - th/2 };
275
+          $leftArrow.css({ left: '-5px' });
276
+          $tooltip.prepend($leftArrow);
277
+          break;
278
+      }
279
+      return position;
280
+    },
281
+    getControlPosition: function(pos) {
282
+      switch (pos)
283
+      {
284
+        case 'TR':
285
+          pos = { 'top' : '10px', 'right' : '10px' };
286
+          break;
287
+
288
+        case 'TL':
289
+          pos = { 'top' : '10px', 'left' : '10px' };
290
+          break;
291
+
292
+        case 'BL':
293
+          pos = { 'bottom' : '10px', 'left' : '10px' };
294
+          break;
295
+
296
+        case 'BR':
297
+          pos = { 'bottom' : '10px', 'right' : '10px' };
298
+          break;
299
+      }
300
+      return pos;
301
+    },
302
+    destroy : function() {
303
+      $('#tourControls').remove();
304
+      $('#tourtip').remove();
305
+      $tooltip.css({ 'display' : 'none' }).html('');
306
+      step = -1;
307
+      started = false;
308
+    }
309
+  };
310
+
311
+  $('#tourNext').live('click', function() {
312
+    methods.next();
313
+  });
314
+
315
+  $('#tourPrev').live('click', function() {
316
+    methods.prev();
317
+  });
318
+
319
+  $('#tourEnd').live('click', function() {
320
+    options.endCallback();
321
+    methods.destroy();
322
+  })
323
+
324
+  $.fn.aSimpleTour = function( method )
325
+  {
326
+    if ( methods[method] ) {
327
+      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
328
+    } 
329
+    else if ( typeof method === 'object' || ! method ) {
330
+      return methods.init.apply( this, arguments );
331
+    } 
332
+    else {
333
+      $.error( 'Method ' +  method + ' does not exist on jQuery.aSimpleTour' );
334
+    }   
335
+  };
336
+
337
+})(jQuery);
338
+
339
+// Direct Access
340
+$.aSimpleTour = function(opts) { $.fn.aSimpleTour(opts); }

+ 7 - 0
web/js/jquery.scrollTo.min.js View File

@@ -0,0 +1,7 @@
1
+/**
2
+ * Copyright (c) 2007-2012 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
3
+ * Dual licensed under MIT and GPL.
4
+ * @author Ariel Flesler
5
+ * @version 1.4.5 BETA
6
+ */
7
+;(function($){var h=$.scrollTo=function(a,b,c){$(window).scrollTo(a,b,c)};h.defaults={axis:'xy',duration:parseFloat($.fn.jquery)>=1.3?0:1,limit:true};h.window=function(a){return $(window)._scrollable()};$.fn._scrollable=function(){return this.map(function(){var a=this,isWin=!a.nodeName||$.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!isWin)return a;var b=(a.contentWindow||a).document||a.ownerDocument||a;return/webkit/i.test(navigator.userAgent)||b.compatMode=='BackCompat'?b.body:b.documentElement})};$.fn.scrollTo=function(e,f,g){if(typeof f=='object'){g=f;f=0}if(typeof g=='function')g={onAfter:g};if(e=='max')e=9e9;g=$.extend({},h.defaults,g);f=f||g.duration;g.queue=g.queue&&g.axis.length>1;if(g.queue)f/=2;g.offset=both(g.offset);g.over=both(g.over);return this._scrollable().each(function(){if(e==null)return;var d=this,$elem=$(d),targ=e,toff,attr={},win=$elem.is('html,body');switch(typeof targ){case'number':case'string':if(/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(targ)){targ=both(targ);break}targ=$(targ,this);if(!targ.length)return;case'object':if(targ.is||targ.style)toff=(targ=$(targ)).offset()}$.each(g.axis.split(''),function(i,a){var b=a=='x'?'Left':'Top',pos=b.toLowerCase(),key='scroll'+b,old=d[key],max=h.max(d,a);if(toff){attr[key]=toff[pos]+(win?0:old-$elem.offset()[pos]);if(g.margin){attr[key]-=parseInt(targ.css('margin'+b))||0;attr[key]-=parseInt(targ.css('border'+b+'Width'))||0}attr[key]+=g.offset[pos]||0;if(g.over[pos])attr[key]+=targ[a=='x'?'width':'height']()*g.over[pos]}else{var c=targ[pos];attr[key]=c.slice&&c.slice(-1)=='%'?parseFloat(c)/100*max:c}if(g.limit&&/^\d+$/.test(attr[key]))attr[key]=attr[key]<=0?0:Math.min(attr[key],max);if(!i&&g.queue){if(old!=attr[key])animate(g.onAfterFirst);delete attr[key]}});animate(g.onAfter);function animate(a){$elem.animate(attr,f,g.easing,a&&function(){a.call(this,e,g)})}}).end()};h.max=function(a,b){var c=b=='x'?'Width':'Height',scroll='scroll'+c;if(!$(a).is('html,body'))return a[scroll]-$(a)[c.toLowerCase()]();var d='client'+c,html=a.ownerDocument.documentElement,body=a.ownerDocument.body;return Math.max(html[scroll],body[scroll])-Math.min(html[d],body[d])};function both(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);