showoff 0.17.2 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
data/locales/pt.yml ADDED
@@ -0,0 +1,160 @@
1
+ pt:
2
+ name: Apresentação Showoff
3
+ menu:
4
+ title: Menu Showoff
5
+ table_of_contents: Índice
6
+ downloads: Downloads
7
+ feedback: Enviando...
8
+ pace:
9
+ label: O palestrante deve...
10
+ slower: Ir mais devagar
11
+ faster: Ir mais rapido
12
+ question:
13
+ label: Faça uma pergunta
14
+ placeholder: Faça uma pergunta...
15
+ feedback:
16
+ label: Envie comentários
17
+ description: Este slide é...
18
+ worst: Ruim
19
+ best: Bom
20
+ why: Por quê...?
21
+ send: Enviar
22
+ edit: Editar Slide Atual
23
+ clear_annotations: Apagar Anotações
24
+ language: Idioma do conteúdo
25
+ close: Fechar
26
+ help: Digite <code>?</code> para ajuda.
27
+ anonymous: Todo conteúdo é anonimo.
28
+ navigation:
29
+ next: Próximo
30
+ previous: Anterior
31
+ loading: carregando apresentação...
32
+ activity_complete: Atividade completada
33
+ follow:
34
+ label: "Modo Seguidor:"
35
+ refresh: "Você tem certeza que quer atualizar o conteúdo do slide?\n\n(Use o `RELOAD` para recarregar completamente a UI inteira)"
36
+ reload: Você tem certeza que quer reiniciar Showoff?
37
+ preshow:
38
+ prompt: Em quanto minutos começar?
39
+ resume: "Resumindo em:"
40
+
41
+ downloads:
42
+ title: Arquivos de Downloads
43
+
44
+ help:
45
+ title: Ajuda
46
+ next: Ir para o próximo slide.
47
+ prev: Ir para o slide anterior.
48
+ contents: Mostrar o Índice.
49
+ follow: Alternar modo seguidor.
50
+ help: Mostrar esta ajuda.
51
+ refresh: Atualizar conteúdo do slide.
52
+ reload: Recarregar Showoff completamente.
53
+ blank: Tela vazia.
54
+ footer: Alternar o rodapé.
55
+ notes: Alternar anotaçōes.
56
+ clear: Limpar resultados de execução do código.
57
+ pause: Pausar a apresentação.
58
+ preshow: Mostrar images de slideshow <tt>preshow</tt> em crônometro.
59
+ execute: Executar o primeiro block de código visível.
60
+ debug: Mostrar informação de debugging.
61
+ close: Fechar
62
+
63
+ stats:
64
+ title: Visualizando Estatísticas
65
+ stray: audiência visualizando slides diferentes do seu.
66
+ idle: audiência não participativa.
67
+ current: Slides que estão sendo visualizados no momento
68
+ elapsed: Tempo gasto em cada slide
69
+ nodata: Nenhum dado a mostrar.
70
+ allcurrent: Toda a audiência esta visualizando o slide do palestrante.
71
+
72
+ forms:
73
+ display: Mostrar Resultados
74
+ save: Salvar
75
+
76
+ presenter:
77
+ topbar:
78
+ annotations: Anotacoōes
79
+ edit: Editar Slide
80
+ report: Relatar Problema com Slide
81
+ stats: Visualizando Estatísticas
82
+ downloads: Downloads
83
+ display: Tela de Apresentação
84
+ print: Imprimir Slides
85
+ settings: Configuraçoōes
86
+ newpage: Abrir em uma nova pagina...
87
+ tooltip:
88
+ annotations: Permitir anotaçōes de subsistema.
89
+ edit: Editar slide atual em uma nova janela.
90
+ report: Relatar Problema com o slide atual.
91
+ stats: Visualizar slides com os quais sua audiência está interagindo.
92
+ downloads: Abrir os arquivos de download em um menu ou nova página.
93
+ display: Permitir Tela de Apresentacão; você deve usá-la no projetor.
94
+ print: Imprimir slides usando uma nova janela.
95
+ settings: Abrir tela de Configuraçōes.
96
+ preview:
97
+ next: Próximo
98
+ previous: Anterior
99
+ mobile:
100
+ update: Atualizar
101
+ notes:
102
+ label: Anotaçoōes Showoff
103
+ personal: Anotaçoōes Pessoais
104
+ timer:
105
+ label: "Cronômetro:"
106
+ start: Iniciar
107
+ pause: Pausar
108
+ resume: Resumir
109
+ cancel: Cancelar
110
+ unit: mminutos
111
+ pace:
112
+ faster: Acelere!
113
+ slower: Desacelere!
114
+ questions: Perguntas da Audiência
115
+ annotation:
116
+ tools: Ferramentas
117
+ lines: Linhas
118
+ shapes: Formas
119
+ status:
120
+ label: "Slides:"
121
+ settings:
122
+ label: Configuracoōes
123
+ close: Fechar
124
+ follower:
125
+ label: Rastreamento de Atualizaçōes
126
+ tooltip: Enviar notificaçōes de alteração de slide.
127
+ description: Quando esta função estiver habilitada, o server do Showoff irá rastrear toda a alteração de slide. Desabilite esta função para visualizar a apresentação sem alterá-la inadvertidamente.
128
+ remote:
129
+ label: Permitir Controle Remoto
130
+ tooltip: Habilita o uso de outros controles.
131
+ description: Quando esta função esta habilitada, você pode carregar o controle em outro navegador (geralmente seu celular) para controlar a apresentação.
132
+ layout:
133
+ label: Layout
134
+ default: Layout Padrão
135
+ thumbs: Mostrar ícone miniatura do slide anterior e do próximo slide.
136
+ beside: Mostrar próximo slide na tela principal do palestrante.
137
+ floating: Abrir o próximo slide em uma nova janela.
138
+ confirmation: As configuraçoōes de segurança do seu navegador requer confirmaçaão antes de abrir uma nova janela.
139
+ open: Abrir Janela
140
+ cancel: Cancelar
141
+ reset:
142
+ label: Limpar configuraçoōes do Showoff.
143
+ tooltip: Reseta configuraçoōes do Showoff UI para os valores padrão.
144
+ language:
145
+ label: Idioma do Conteúdo
146
+ tooltip: Selecione traducoōes ou auto-selecione com base nas configuracoōes de seu navegador.
147
+ description: Esta apresentação esta disponível em outros idiomas. Escolha o idioma que você gostaria de visualizar ou deixe em <tt>automatic</tt> para usar as configuraçōes do seu navegador.
148
+ print:
149
+ label: Escolha o tipo de visualizaçao de anotaçōes
150
+ description: Selecione o conteúdo que voceêê gostaria de mostrar abaixo dos slides.
151
+ none: Não incluir anotaçōes
152
+ notes: Anotaçōes do Palestrante
153
+ handouts: Brochura para Audiência
154
+
155
+ language:
156
+ auto: Automática
157
+ disable: Desabilitar Traduçōes
158
+
159
+ error:
160
+ file_not_found: Arquivo nao Encontrado!
@@ -40,6 +40,10 @@
40
40
  #topbar a,
41
41
  #topbar .ui-widget {
42
42
  text-decoration: none;
43
+ -webkit-user-select: none;
44
+ -moz-user-select: none;
45
+ -ms-user-select: none;
46
+ user-select: none;
43
47
  }
44
48
 
45
49
  #topbar a i {
@@ -50,6 +54,11 @@
50
54
  #topbar .ui-widget:hover {
51
55
  background-color: #263238;
52
56
  }
57
+ #topbar a:active,
58
+ #topbar a.enabled:active,
59
+ #topbar .ui-widget:active {
60
+ background-color: #2e424c;
61
+ }
53
62
 
54
63
  #close-sidebar {
55
64
  padding: .25em;
@@ -106,13 +115,14 @@
106
115
  display: none;
107
116
  position: absolute;
108
117
  z-index: 2147483647;
109
- top: 3em;
118
+ top: 2.95em;
110
119
  left: 25%;
111
120
  max-height: 80%;
112
121
  width: 50%;
113
122
  padding-bottom: 1em;
114
123
  border-radius: 0 0 .5em .5em;
115
124
  overflow: auto;
125
+ background-color: #263238;
116
126
  }
117
127
 
118
128
  #presenterPopup a {
@@ -176,6 +186,9 @@
176
186
  margin: 2px 0px;
177
187
  }
178
188
 
189
+ #timerSection #startTimer {
190
+ float: right;
191
+ }
179
192
  #timerSection #pauseTimer {
180
193
  float: left;
181
194
  display: none;
@@ -97,8 +97,14 @@ pre code {
97
97
  z-index: 2147483647; /* max, see http://www.puidokas.com/max-z-index/ */
98
98
  display: none;
99
99
  }
100
+ #footer .container {
101
+ border: 1px solid #ccc;
102
+ padding: 2px 6px;
103
+ margin: 0 3px;
104
+ border-radius: 3px;
105
+ }
100
106
  #followMode {
101
- display: none;
107
+ font-weight: bold;
102
108
  }
103
109
  #pauseScreen {
104
110
  background: rgba(0, 0, 0, 0.85);
@@ -151,7 +157,8 @@ pre code {
151
157
  margin: 2em;
152
158
  }
153
159
 
154
- .content img {
160
+ .content img,
161
+ .content svg {
155
162
  display:block;
156
163
  margin-left:auto;
157
164
  margin-right:auto;
@@ -265,8 +272,7 @@ pre code {
265
272
 
266
273
  .offscreen { position:absolute; top:0; left:-9999px; overflow:hidden; }
267
274
 
268
- #debugInfo,
269
- #slideFilename {
275
+ body.presenter #debugInfo {
270
276
  margin-left: 30px;
271
277
  }
272
278
 
@@ -386,10 +392,15 @@ img#disconnected {
386
392
  clear: both;
387
393
  }
388
394
 
395
+ .optionWrapper,
389
396
  .buttonWrapper {
390
397
  line-height: 48px;
391
398
  padding: 0 16px;
392
399
  font-weight: bold;
400
+ -webkit-user-select: none;
401
+ -moz-user-select: none;
402
+ -ms-user-select: none;
403
+ user-select: none;
393
404
  }
394
405
 
395
406
  .buttonWrapper:hover,
@@ -508,6 +519,10 @@ img#disconnected {
508
519
  text-decoration: line-through;
509
520
  color: #ccc;
510
521
  }
522
+ #languageMenu {
523
+ line-height: 2em;
524
+ }
525
+
511
526
 
512
527
  /* End Sidebar styling */
513
528
 
@@ -754,6 +769,36 @@ form .element {
754
769
  display: none;
755
770
  }
756
771
 
772
+ /**********************************
773
+ *** form answer key ***
774
+ **********************************/
775
+
776
+ /* no, the option styling will likely not do anything */
777
+ .slide.answerkey form option.incorrect,
778
+ .slide.answerkey form label.incorrect {
779
+ text-decoration: line-through;
780
+ font-weight: 100;
781
+ opacity: .7;
782
+ }
783
+ .slide.answerkey form label.correct,
784
+ .slide.answerkey form option.correct {
785
+ font-weight: 900;
786
+ }
787
+ /* Be careful with order here; these rules depend on cascading order */
788
+ .slide.answerkey input + option,
789
+ .slide.answerkey input + label.incorrect,
790
+ .slide.answerkey input:checked + label.correct,
791
+ .slide.answerkey input:checked + option.correct {
792
+ color: #00AA00; /* green */
793
+ }
794
+ .slide.answerkey input:checked + option,
795
+ .slide.answerkey input:checked + label.incorrect,
796
+ .slide.answerkey input + label.correct,
797
+ .slide.answerkey input + option.correct {
798
+ color: #e74c3c; /* red */
799
+ }
800
+
801
+
757
802
  /*****************
758
803
  *** modals ***
759
804
  *****************/
@@ -1253,6 +1298,11 @@ h1.section_title {
1253
1298
  margin-right:auto;
1254
1299
  }
1255
1300
 
1301
+ /* keep the activity toggle from showing in printed output */
1302
+ .slide.activity .activityToggle {
1303
+ display: none;
1304
+ }
1305
+
1256
1306
  /* Styling to make the handout notes appear in the printed output. */
1257
1307
  .notes-section {
1258
1308
  display: block;
@@ -11,10 +11,6 @@ $(document).ready(function(){
11
11
  // set up the presenter modes
12
12
  mode = { track: true, follow: true, update: true, slave: false, notes: false, annotations: false, layout: 'default'};
13
13
 
14
- // attempt to open another window for the presentation if the mode defaults
15
- // to enabling this. It does not by default, so this is likely a no-op.
16
- openSlave();
17
-
18
14
  // the presenter window doesn't need the reload on resize bit
19
15
  $(window).unbind('resize');
20
16
 
@@ -26,7 +22,7 @@ $(document).ready(function(){
26
22
  // browser security causes a click event to react differently than an actual user click. Even though they're the same damn thing.
27
23
  // $("#report").click( function() { reportIssue() });
28
24
  $("#slaveWindow").click( function() { toggleSlave() });
29
- $("#printSlides").click( function() { printSlides() });
25
+ $("#printSlides").click( function() { printDialog() });
30
26
  $("#settings").click( function() { $("#settings-modal").dialog("open"); });
31
27
  $("#slideSource a").click( function() { openEditor() });
32
28
  $("#notesToggle").click( function() { toggleNotes() });
@@ -51,10 +47,16 @@ $(document).ready(function(){
51
47
  $('#downloadslink').click(function(e) { presenterPopupToggle('/download', e); });
52
48
 
53
49
  $('#layoutSelector').change(function(e) { chooseLayout(e.target.value); });
54
-
55
50
  chooseLayout(null);
56
51
 
57
- $("#settings-modal").dialog({
52
+ // the language selector is configured in showoff.js
53
+
54
+ // must be defined using [] syntax for a variable button name on IE.
55
+ var closeLabel = I18n.t('presenter.settings.close');
56
+ var buttons = {};
57
+ buttons[closeLabel] = function() { $(this).dialog( "close" ); };
58
+
59
+ $("#settings-modal, #print-modal").dialog({
58
60
  autoOpen: false,
59
61
  dialogClass: "no-close",
60
62
  draggable: false,
@@ -62,11 +64,7 @@ $(document).ready(function(){
62
64
  modal: true,
63
65
  resizable: false,
64
66
  width: 400,
65
- buttons: {
66
- Close: function() {
67
- $( this ).dialog( "close" );
68
- }
69
- }
67
+ buttons: buttons
70
68
  });
71
69
 
72
70
  $("#annotationsToggle").checkboxradio({
@@ -152,6 +150,7 @@ $(document).ready(function(){
152
150
  $('#followerToggle').change( toggleUpdater );
153
151
  $('#annotationsToggle').change( toggleAnnotations );
154
152
 
153
+ initializeSettings();
155
154
  setInterval(function() { updatePace() }, 1000);
156
155
 
157
156
  setInterval(function() {
@@ -159,7 +158,7 @@ $(document).ready(function(){
159
158
  var percent = json['stray_p'];
160
159
  if(percent > 25) {
161
160
  $('#topbar #statslink').addClass('warning');
162
- $('#topbar #statslink').attr('title', percent + "% of your audience is not viewing the same slide you are.");
161
+ $('#topbar #statslink').attr('title', percent + '%' + I18n.t('stats.stray'));
163
162
  }
164
163
  else {
165
164
  $('#stray').hide(); // in case the popup is open
@@ -200,12 +199,17 @@ $(document).ready(function(){
200
199
 
201
200
  function presenterPopupToggle(page, event) {
202
201
  event.preventDefault();
202
+ // remove class from both so we don't lose an active state if user clicks the wrong item
203
+ $('#statslink').removeClass('enabled');
204
+ $('#downloadslink').removeClass('enabled');
205
+
203
206
  var popup = $('#presenterPopup');
204
207
  if (popup.length > 0) {
205
208
  popup.slideUp(200, function () {
206
209
  popup.remove();
207
210
  });
208
211
  } else {
212
+ $(event.target).addClass('enabled');
209
213
  popup = $('<div>');
210
214
  popup.attr('id', 'presenterPopup');
211
215
  $.get(page, function(data) {
@@ -216,7 +220,7 @@ function presenterPopupToggle(page, event) {
216
220
  href: page,
217
221
  target: '_new'
218
222
  });
219
- link.text('Open in a new page...');
223
+ link.text(I18n.t('presenter.topbar.newpage'));
220
224
 
221
225
  content.attr('id', page.substring(1, page.length));
222
226
  content.append(link);
@@ -261,22 +265,27 @@ function windowIsOpen(window) {
261
265
 
262
266
  function toggleSlave() {
263
267
  mode.slave = !mode.slave;
264
- openSlave();
268
+ if (mode.slave) {
269
+ openSlave();
270
+ } else {
271
+ closeSlave();
272
+ }
265
273
  }
266
274
 
267
275
  // Open, or maintain connection & reopen slave window.
268
276
  function openSlave()
269
277
  {
270
- if (mode.slave) {
271
- try {
272
- if(windowIsClosed(slaveWindow)){
273
- slaveWindow = window.open('/' + window.location.hash, 'toolbar');
274
- }
275
- else if(slaveWindow.location.hash != window.location.hash) {
276
- // maybe we need to reset content?
277
- slaveWindow.location.href = '/' + window.location.hash;
278
- }
278
+ try {
279
+ if(windowIsClosed(slaveWindow)){
280
+ slaveWindow = window.open('/' + window.location.hash, 'toolbar');
281
+ }
282
+ else if(slaveWindow.location.hash != window.location.hash) {
283
+ // maybe we need to reset content?
284
+ slaveWindow.location.href = '/' + window.location.hash;
285
+ }
279
286
 
287
+ // give the window time to load before poking at it
288
+ window.setTimeout(function() {
280
289
  // maintain the pointer back to the parent.
281
290
  slaveWindow.presenterView = window;
282
291
  slaveWindow.mode = { track: false, slave: true, follow: false };
@@ -284,26 +293,41 @@ function openSlave()
284
293
  // Add a class to differentiate from the audience view
285
294
  slaveWindow.document.getElementById("preso").className = 'display';
286
295
 
287
- $('#slaveWindow').addClass('enabled');
288
- }
289
- catch(e) {
290
- console.log('Failed to open or connect display window. Popup blocker?');
291
- }
296
+ // call back and update the parent presenter if the window is closed
297
+ slaveWindow.onunload = function(e) {
298
+ slaveWindow.opener.closeSlave(true);
299
+ };
300
+ }, 500);
292
301
 
293
- // Set up a maintenance loop to keep the connection between windows. I wish there were a cleaner way to do this.
294
- if (typeof maintainSlave == 'undefined') {
295
- maintainSlave = setInterval(openSlave, 1000);
296
- }
302
+ $('#slaveWindow').addClass('enabled');
297
303
  }
298
- else {
299
- try {
304
+ catch(e) {
305
+ console.log('Failed to open or connect display window. Popup blocker?');
306
+ }
307
+ }
308
+
309
+ function closeSlave(calledByChild) {
310
+ try {
311
+ mode.slave = false;
312
+ $('#slaveWindow').removeClass('enabled');
313
+
314
+ if(calledByChild) {
315
+ // if this is called by the display view, we don't want to try to close it again.
316
+ // browsers are the worst. If the user hit *refresh*, then this should reconnect the display view
317
+ window.setTimeout(function() {
318
+ if(! windowIsClosed(slaveWindow)) {
319
+ openSlave();
320
+ }
321
+ }, 500);
322
+ } else {
323
+ // called normally and close the display view
300
324
  slaveWindow && slaveWindow.close();
301
- $('#slaveWindow').removeClass('enabled');
302
- }
303
- catch (e) {
304
- console.log('Display window failed to close properly.');
305
325
  }
306
326
  }
327
+ catch (e) {
328
+ console.log('Display window failed to close properly.');
329
+ }
330
+
307
331
  }
308
332
 
309
333
  function nextSlideNum(url) {
@@ -357,7 +381,7 @@ function toggleNotes() {
357
381
  if (mode.notes) {
358
382
  try {
359
383
  if(windowIsClosed(notesWindow)){
360
- notesWindow = blankStyledWindow("Showoff Notes", 'width=350,height=450', 'notes', true);
384
+ notesWindow = blankStyledWindow(I18n.t('notes.label'), 'width=350,height=450', 'notes', true);
361
385
  window.setTimeout(function() {
362
386
  // call back and update the parent presenter if the window is closed
363
387
  notesWindow.onunload = function(e) {
@@ -438,15 +462,53 @@ function blankStyledWindow(title, dimensions, classes, resizable) {
438
462
  return newWindow;
439
463
  }
440
464
 
441
- function printSlides()
465
+ function printDialog() {
466
+ var list = $('#print-modal #print-sections');
467
+
468
+ if(! list.hasClass('processed')) {
469
+ sections = getAllSections()
470
+ sections.unshift('') // add the "none" option
471
+ sections.forEach(function(section) {
472
+ var link = $('<a>');
473
+ var item = $('<li>');
474
+ link.attr('href', '#');
475
+ link.click(function(){
476
+ printSlides(section);
477
+ });
478
+
479
+ switch(section) {
480
+ case '':
481
+ link.text(I18n.t('presenter.print.none'));
482
+ break;
483
+ case 'notes':
484
+ link.text(I18n.t('presenter.print.notes'));
485
+ break;
486
+ case 'handouts':
487
+ link.text(I18n.t('presenter.print.handouts'));
488
+ break;
489
+ default:
490
+ link.text(section);
491
+ }
492
+
493
+ item.append(link);
494
+ list.append(item);
495
+ });
496
+ list.addClass('processed');
497
+ }
498
+
499
+ $("#print-modal").dialog("open");
500
+ }
501
+
502
+ function printSlides(section)
442
503
  {
443
504
  try {
444
- var printWindow = window.open('/print');
505
+ var printWindow = window.open('/print/'+section);
445
506
  printWindow.window.print();
446
507
  }
447
508
  catch(e) {
448
509
  console.log('Failed to open print window. Popup blocker?');
449
510
  }
511
+ $("#print-modal").dialog("close");
450
512
  }
451
513
 
452
514
  function postQuestion(question, questionID) {
@@ -551,7 +613,7 @@ gotoSlide = function (slideNum)
551
613
  if ( !mobile() ) {
552
614
  $("#navigation li li").get(slidenum).scrollIntoView();
553
615
  }
554
- postSlide()
616
+ postSlide();
555
617
  }
556
618
 
557
619
  // override with an alternate implementation.
@@ -657,14 +719,19 @@ function postSlide() {
657
719
  }
658
720
 
659
721
  var nextIndex = slidenum + 1;
660
- var nextSlide = (nextIndex >= slides.size()) ? '' : slides.eq(nextIndex).html();
661
- var prevSlide = (slidenum > 0) ? slides.eq(slidenum - 1).html() : ''
722
+ var nextSlide = (nextIndex >= slides.size()) ? $('') : slides.eq(nextIndex);
723
+ var nextThumb = $('#nextSlide .container');
724
+ var prevSlide = (slidenum > 0) ? slides.eq(slidenum - 1) : $('');
725
+ var prevThumb = $('#prevSlide .container');
726
+
727
+ nextThumb.html(nextSlide.html());
728
+ prevThumb.html(prevSlide.html());
662
729
 
663
- $('#nextSlide .container').html(nextSlide);
664
- $('#prevSlide .container').html(prevSlide);
730
+ copyBackground(nextSlide, nextThumb);
731
+ copyBackground(prevSlide, prevThumb);
665
732
 
666
733
  if (windowIsOpen(nextWindow)) {
667
- $(nextWindow.document.body).html(nextSlide);
734
+ $(nextWindow.document.body).html(nextSlide.html());
668
735
  }
669
736
 
670
737
  if (windowIsOpen(notesWindow)) {
@@ -674,7 +741,7 @@ function postSlide() {
674
741
  var fileName = currentSlide.children('div').first().attr('ref');
675
742
  $('#slideFile').text(fileName);
676
743
  $('#progress').progressbar({ max: slideTotal })
677
- .progressbar('value', slidenum);
744
+ .progressbar('value', slidenum+1);
678
745
 
679
746
  $("#notes div.form.wrapper").each(function(e) {
680
747
  renderFormInterval = renderFormWatcher($(this));
@@ -870,6 +937,12 @@ function stopTimer() {
870
937
  unpinSidebar('timer');
871
938
  }
872
939
 
940
+ function initializeSettings() {
941
+ // enable this if we are the "master" presenter
942
+ $("#followerToggle").prop("checked", master);
943
+ mode.update = $("#followerToggle").prop("checked");
944
+ }
945
+
873
946
  /********************
874
947
  Follower Code
875
948
  ********************/