[TASK] Migrate TYPO3/CMS/Backend/Wizard to TypeScript 69/59669/6
authorFrank Naegler <frank.naegler@typo3.org>
Fri, 8 Feb 2019 12:44:01 +0000 (13:44 +0100)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Fri, 1 Mar 2019 15:53:20 +0000 (16:53 +0100)
Resolves: #82612
Releases: master
Change-Id: I6dd7d2138afe98bd60889dd4f25b7a3b2dca287d
Reviewed-on: https://review.typo3.org/c/59669
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Build/types/TYPO3/index.d.ts
typo3/sysext/backend/Resources/Private/TypeScript/Localization.ts
typo3/sysext/backend/Resources/Private/TypeScript/Wizard.ts [new file with mode: 0644]
typo3/sysext/backend/Resources/Public/JavaScript/Localization.js
typo3/sysext/backend/Resources/Public/JavaScript/Wizard.js

index 6e09bf0..f542594 100644 (file)
@@ -21,6 +21,7 @@ declare namespace TYPO3 {
   export let Storage: any;
   export let Tooltip: any;
   export let Utility: any;
+  export let Wizard: any;
   export const lang: { [key: string]: string };
   export const settings: any;
   export const configuration: any;
index 9b51395..c512615 100644 (file)
@@ -14,7 +14,7 @@
 import {SeverityEnum} from './Enum/Severity';
 import * as $ from 'jquery';
 import Icons = require('./Icons');
-import Wizard = require('TYPO3/CMS/Backend/Wizard');
+import Wizard = require('./Wizard');
 
 type LanguageRecord = {
   uid: number;
@@ -255,7 +255,7 @@ class Localization {
                   } else {
                     Wizard.lockNextStep();
                   }
-                }).on('change', '.t3js-localization-toggle-column', (toggleEvt): void => {
+                }).on('change', '.t3js-localization-toggle-column', (toggleEvt: JQueryEventObject): void => {
                   const $me = $(toggleEvt.currentTarget);
                   const $children = $me.closest('fieldset').find('.t3js-localization-toggle-record');
 
diff --git a/typo3/sysext/backend/Resources/Private/TypeScript/Wizard.ts b/typo3/sysext/backend/Resources/Private/TypeScript/Wizard.ts
new file mode 100644 (file)
index 0000000..82cd73b
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+import {SeverityEnum} from './Enum/Severity';
+import * as $ from 'jquery';
+import Modal = require('./Modal');
+import Severity = require('./Severity');
+import Icons = require('./Icons');
+
+
+interface WizardSettings {
+  [key: string]: any;
+}
+
+interface WizardSetup {
+  slides: Array<any>;
+  settings: WizardSettings;
+  forceSelection: boolean;
+  $carousel: JQuery;
+}
+
+interface Slide {
+  identifier: string;
+  title: string;
+  content: string|JQuery;
+  severity: SeverityEnum;
+  callback?: Function;
+}
+
+/**
+ * Module: TYPO3/CMS/Backend/Wizard
+ * @exports TYPO3/CMS/Backend/Wizard
+ */
+class Wizard {
+  private setup: WizardSetup;
+  private readonly originalSetup: WizardSetup;
+
+  constructor() {
+    this.setup = {
+      slides: [],
+      settings: {},
+      forceSelection: true,
+      $carousel: null,
+    };
+    this.originalSetup = $.extend(true, {}, this.setup);
+  }
+
+  public set(key: string, value: any): Wizard {
+    this.setup.settings[key] = value;
+    return this;
+  }
+
+  public addSlide(
+    identifier: string,
+    title: string,
+    content: string = '',
+    severity: SeverityEnum = SeverityEnum.info,
+    callback?: Function,
+  ): Wizard {
+    const slide: Slide = {
+      identifier: identifier,
+      title: title,
+      content: content,
+      severity: severity,
+      callback: callback,
+    };
+    this.setup.slides.push(slide);
+    return this;
+  }
+
+  public addFinalProcessingSlide(callback?: Function): JQueryPromise<any> {
+    if (!callback) {
+      callback = (): void => {
+        this.dismiss();
+      };
+    }
+
+    return Icons.getIcon('spinner-circle-dark', Icons.sizes.large, null, null).done((markup: string) => {
+      let $processingSlide = $('<div />', {class: 'text-center'}).append(markup);
+      this.addSlide(
+        'final-processing-slide', top.TYPO3.lang['wizard.processing.title'],
+        $processingSlide[0].outerHTML,
+        Severity.info,
+        callback,
+      );
+    });
+  }
+
+  public show(): void {
+    let $slides = this.generateSlides();
+    let firstSlide = this.setup.slides[0];
+
+    Modal.confirm(
+      firstSlide.title,
+      $slides,
+      firstSlide.severity,
+      [{
+        text: top.TYPO3.lang['wizard.button.cancel'],
+        active: true,
+        btnClass: 'btn-default',
+        name: 'cancel',
+        trigger: (): void => {
+          this.getComponent().trigger('wizard-dismiss');
+        },
+      }, {
+        text: top.TYPO3.lang['wizard.button.next'],
+        btnClass: 'btn-' + Severity.getCssClass(firstSlide.severity),
+        name: 'next',
+      }],
+    );
+
+    if (this.setup.forceSelection) {
+      this.lockNextStep();
+    }
+
+    this.addProgressBar();
+    this.initializeEvents();
+
+    this.getComponent().on('wizard-visible', (): void => {
+      this.runSlideCallback(firstSlide, this.setup.$carousel.find('.item').first());
+    }).on('wizard-dismissed', (): void => {
+      this.setup = $.extend(true, {}, this.originalSetup);
+    });
+  }
+
+  public getComponent(): JQuery {
+    if (this.setup.$carousel === null) {
+      this.generateSlides();
+    }
+    return this.setup.$carousel;
+  }
+
+  public dismiss(): void {
+    Modal.dismiss();
+  }
+
+  public lockNextStep(): JQuery {
+    let $button = this.setup.$carousel.closest('.modal').find('button[name="next"]');
+    $button.prop('disabled', true);
+    return $button;
+  }
+
+  public unlockNextStep(): JQuery {
+    let $button = this.setup.$carousel.closest('.modal').find('button[name="next"]');
+    $button.prop('disabled', false);
+    return $button;
+  }
+
+  private initializeEvents(): void {
+    let $modal = this.setup.$carousel.closest('.modal');
+    let $modalTitle = $modal.find('.modal-title');
+    let $modalFooter = $modal.find('.modal-footer');
+    let $nextButton = $modalFooter.find('button[name="next"]');
+
+    $nextButton.on('click', (): void => {
+      this.setup.$carousel.carousel('next');
+    });
+
+    this.setup.$carousel.on('slide.bs.carousel', (): void => {
+      let nextSlideNumber = this.setup.$carousel.data('currentSlide') + 1;
+      let currentIndex = this.setup.$carousel.data('currentIndex') + 1;
+
+      $modalTitle.text(this.setup.slides[currentIndex].title);
+
+      this.setup.$carousel.data('currentSlide', nextSlideNumber);
+      this.setup.$carousel.data('currentIndex', currentIndex);
+
+      if (nextSlideNumber >= this.setup.$carousel.data('realSlideCount')) {
+        // Point of no return - hide modal footer disable any closing ability
+        $modal.find('.modal-header .close').remove();
+        $modalFooter.slideUp();
+      } else {
+        $modalFooter.find('.progress-bar')
+          .width(this.setup.$carousel.data('initialStep') * nextSlideNumber + '%')
+          .text(top.TYPO3.lang['wizard.progress']
+            .replace('{0}', nextSlideNumber)
+            .replace('{1}', this.setup.$carousel.data('slideCount')));
+      }
+
+      $nextButton
+        .removeClass('btn-' + Severity.getCssClass(this.setup.slides[currentIndex - 1].severity))
+        .addClass('btn-' + Severity.getCssClass(this.setup.slides[currentIndex].severity));
+
+      $modal
+        .removeClass('modal-severity-' + Severity.getCssClass(this.setup.slides[currentIndex - 1].severity))
+        .addClass('modal-severity-' + Severity.getCssClass(this.setup.slides[currentIndex].severity));
+    }).on('slid.bs.carousel', (evt: JQueryEventObject): void => {
+      let currentIndex = this.setup.$carousel.data('currentIndex');
+      let slide = this.setup.slides[currentIndex];
+
+      this.runSlideCallback(slide, $(evt.relatedTarget));
+
+      if (this.setup.forceSelection) {
+        this.lockNextStep();
+      }
+    });
+
+    /**
+     * Custom event, closes the wizard
+     */
+    let cmp = this.getComponent();
+    cmp.on('wizard-dismiss', this.dismiss);
+
+    Modal.currentModal.on('hidden.bs.modal', (): void => {
+      cmp.trigger('wizard-dismissed');
+    }).on('shown.bs.modal', (): void => {
+      cmp.trigger('wizard-visible');
+    });
+  }
+
+  private runSlideCallback(slide: Slide, $slide: JQuery): void {
+    if (typeof slide.callback === 'function') {
+      slide.callback($slide, this.setup.settings, slide.identifier);
+    }
+  }
+
+  private addProgressBar(): void {
+    let realSlideCount = this.setup.$carousel.find('.item').length;
+    let slideCount = Math.max(1, realSlideCount);
+    let initialStep;
+    let $modal = this.setup.$carousel.closest('.modal');
+    let $modalFooter = $modal.find('.modal-footer');
+
+    initialStep = Math.round(100 / slideCount);
+
+    this.setup.$carousel
+      .data('initialStep', initialStep)
+      .data('slideCount', slideCount)
+      .data('realSlideCount', realSlideCount)
+      .data('currentIndex', 0)
+      .data('currentSlide', 1);
+
+    // Append progress bar to modal footer
+    if (slideCount > 1) {
+      $modalFooter.prepend(
+        $('<div />', {class: 'progress'}).append(
+          $('<div />', {
+            role: 'progressbar',
+            class: 'progress-bar',
+            'aria-valuemin': 0,
+            'aria-valuenow': initialStep,
+            'aria-valuemax': 100,
+          }).width(initialStep + '%').text(
+            top.TYPO3.lang['wizard.progress']
+              .replace('{0}', '1')
+              .replace('{1}', slideCount),
+          ),
+        ),
+      );
+    }
+  }
+
+  private generateSlides(): JQuery {
+    // Check whether the slides were already generated
+    if (this.setup.$carousel !== null) {
+      return this.setup.$carousel;
+    }
+
+    let slides = '<div class="carousel slide" data-ride="carousel" data-interval="false">'
+      + '<div class="carousel-inner" role="listbox">';
+
+    for (let i = 0; i < this.setup.slides.length; ++i) {
+      let currentSlide: Slide = this.setup.slides[i];
+      let slideContent = currentSlide.content;
+
+      if (typeof slideContent === 'object') {
+        slideContent = slideContent.html();
+      }
+      slides += '<div class="item" data-slide="' + currentSlide.identifier + '">' + slideContent + '</div>';
+    }
+
+    slides += '</div></div>';
+
+    this.setup.$carousel = $(slides);
+    this.setup.$carousel.find('.item').first().addClass('active');
+
+    return this.setup.$carousel;
+  }
+}
+
+let wizardObject;
+try {
+  // fetch from opening window
+  if (window.opener && window.opener.TYPO3 && window.opener.TYPO3.Wizard) {
+    wizardObject = window.opener.TYPO3.Wizard;
+  }
+
+  // fetch from parent
+  if (parent && parent.window.TYPO3 && parent.window.TYPO3.Wizard) {
+    wizardObject = parent.window.TYPO3.Wizard;
+  }
+
+  // fetch object from outer frame
+  if (top && top.TYPO3 && top.TYPO3.Wizard) {
+    wizardObject = top.TYPO3.Wizard;
+  }
+} catch (e) {
+  // This only happens if the opener, parent or top is some other url (eg a local file)
+  // which loaded the current window. Then the browser's cross domain policy jumps in
+  // and raises an exception.
+  // For this case we are safe and we can create our global object below.
+}
+
+if (!wizardObject) {
+  wizardObject = new Wizard();
+
+  // attach to global frame
+  if (typeof TYPO3 !== 'undefined') {
+    TYPO3.Wizard = wizardObject;
+  }
+}
+
+export = wizardObject;
index 83fedb4..7e681c5 100644 (file)
@@ -10,4 +10,4 @@
  *
  * The TYPO3 project - inspiring people to share!
  */
-var __values=this&&this.__values||function(e){var t="function"==typeof Symbol&&e[Symbol.iterator],a=0;return t?t.call(e):{next:function(){return e&&a>=e.length&&(e=void 0),{value:e&&e[a++],done:!e}}}};define(["require","exports","./Enum/Severity","jquery","./Icons","TYPO3/CMS/Backend/Wizard"],function(e,t,a,n,o,l){"use strict";return new(function(){function e(){var e=this;this.triggerButton=".t3js-localize",this.localizationMode=null,this.sourceLanguage=null,this.records=[],n(function(){e.initialize()})}return e.prototype.initialize=function(){var e=this,t=this;o.getIcon("actions-localize",o.sizes.large).done(function(i){o.getIcon("actions-edit-copy",o.sizes.large).done(function(c){n(t.triggerButton).removeClass("disabled"),n(document).on("click",t.triggerButton,function(t){t.preventDefault();var r=n(t.currentTarget),d=[],s="";r.data("allowTranslate")&&d.push('<div class="row"><div class="btn-group col-sm-3"><label class="btn btn-block btn-default t3js-localization-option" data-helptext=".t3js-helptext-translate">'+i+'<input type="radio" name="mode" id="mode_translate" value="localize" style="display: none"><br>Translate</label></div><div class="col-sm-9"><p class="t3js-helptext t3js-helptext-translate text-muted">'+TYPO3.lang["localize.educate.translate"]+"</p></div></div>"),r.data("allowCopy")&&d.push('<div class="row"><div class="col-sm-3 btn-group"><label class="btn btn-block btn-default t3js-localization-option" data-helptext=".t3js-helptext-copy">'+c+'<input type="radio" name="mode" id="mode_copy" value="copyFromLanguage" style="display: none"><br>Copy</label></div><div class="col-sm-9"><p class="t3js-helptext t3js-helptext-copy text-muted">'+TYPO3.lang["localize.educate.copy"]+"</p></div></div>"),s+='<div data-toggle="buttons">'+d.join("<hr>")+"</div>",l.addSlide("localize-choose-action",TYPO3.lang["localize.wizard.header_page"].replace("{0}",r.data("page")).replace("{1}",r.data("languageName")),s,a.SeverityEnum.info),l.addSlide("localize-choose-language",TYPO3.lang["localize.view.chooseLanguage"],"",a.SeverityEnum.info,function(t){o.getIcon("spinner-circle-dark",o.sizes.large).done(function(a){t.html('<div class="text-center">'+a+"</div>"),e.loadAvailableLanguages(parseInt(r.data("pageId"),10),parseInt(r.data("languageId"),10)).done(function(a){if(1===a.length)return e.sourceLanguage=a[0].uid,void l.unlockNextStep().trigger("click");l.getComponent().on("click",".t3js-language-option",function(t){var a=n(t.currentTarget).find('input[type="radio"]');e.sourceLanguage=a.val(),console.log("Localization.ts@132",e.sourceLanguage),l.unlockNextStep()});var o,i,c=n("<div />",{class:"row","data-toggle":"buttons"});try{for(var r=__values(a),d=r.next();!d.done;d=r.next()){var s=d.value;c.append(n("<div />",{class:"col-sm-4"}).append(n("<label />",{class:"btn btn-default btn-block t3js-language-option option"}).text(" "+s.title).prepend(s.flagIcon).prepend(n("<input />",{type:"radio",name:"language",id:"language"+s.uid,value:s.uid,style:"display: none;"}))))}}catch(e){o={error:e}}finally{try{d&&!d.done&&(i=r.return)&&i.call(r)}finally{if(o)throw o.error}}t.empty().append(c)})})}),l.addSlide("localize-summary",TYPO3.lang["localize.view.summary"],"",a.SeverityEnum.info,function(t){o.getIcon("spinner-circle-dark",o.sizes.large).done(function(e){t.html('<div class="text-center">'+e+"</div>")}),e.getSummary(parseInt(r.data("pageId"),10),parseInt(r.data("languageId"),10)).done(function(a){t.empty(),e.records=[];var o=a.columns.columns;a.columns.columnList.forEach(function(l){if(void 0!==a.records[l]){var i=o[l],c=n("<div />",{class:"row"});a.records[l].forEach(function(t){var a=" ("+t.uid+") "+t.title;e.records.push(t.uid),c.append(n("<div />",{class:"col-sm-6"}).append(n("<div />",{class:"input-group"}).append(n("<span />",{class:"input-group-addon"}).append(n("<input />",{type:"checkbox",class:"t3js-localization-toggle-record",id:"record-uid-"+t.uid,checked:"checked","data-uid":t.uid,"aria-label":a})),n("<label />",{class:"form-control",for:"record-uid-"+t.uid}).text(a).prepend(t.icon))))}),t.append(n("<fieldset />",{class:"localization-fieldset"}).append(n("<label />").text(i).prepend(n("<input />",{class:"t3js-localization-toggle-column",type:"checkbox",checked:"checked"})),c))}}),l.unlockNextStep(),l.getComponent().on("change",".t3js-localization-toggle-record",function(t){var a=n(t.currentTarget),o=a.data("uid"),i=a.closest("fieldset"),c=i.find(".t3js-localization-toggle-column");if(a.is(":checked"))e.records.push(o);else{var r=e.records.indexOf(o);r>-1&&e.records.splice(r,1)}var d=i.find(".t3js-localization-toggle-record"),s=i.find(".t3js-localization-toggle-record:checked");c.prop("checked",s.length>0),c.prop("indeterminate",s.length>0&&s.length<d.length),e.records.length>0?l.unlockNextStep():l.lockNextStep()}).on("change",".t3js-localization-toggle-column",function(e){var t=n(e.currentTarget),a=t.closest("fieldset").find(".t3js-localization-toggle-record");a.prop("checked",t.is(":checked")),a.trigger("change")})})}),l.addFinalProcessingSlide(function(){e.localizeRecords(parseInt(r.data("pageId"),10),parseInt(r.data("languageId"),10),e.records).done(function(){l.dismiss(),document.location.reload()})}).done(function(){l.show(),l.getComponent().on("click",".t3js-localization-option",function(t){var a=n(t.currentTarget),o=a.find('input[type="radio"]');if(a.data("helptext")){var i=n(t.delegateTarget);i.find(".t3js-helptext").addClass("text-muted"),i.find(a.data("helptext")).removeClass("text-muted")}e.localizationMode=o.val(),l.unlockNextStep()})})})})})},e.prototype.loadAvailableLanguages=function(e,t){return n.ajax({url:TYPO3.settings.ajaxUrls.page_languages,data:{pageId:e,languageId:t}})},e.prototype.getSummary=function(e,t){return n.ajax({url:TYPO3.settings.ajaxUrls.records_localize_summary,data:{pageId:e,destLanguageId:t,languageId:this.sourceLanguage}})},e.prototype.localizeRecords=function(e,t,a){return n.ajax({url:TYPO3.settings.ajaxUrls.records_localize,data:{pageId:e,srcLanguageId:this.sourceLanguage,destLanguageId:t,action:this.localizationMode,uidList:a}})},e}())});
\ No newline at end of file
+var __values=this&&this.__values||function(e){var t="function"==typeof Symbol&&e[Symbol.iterator],a=0;return t?t.call(e):{next:function(){return e&&a>=e.length&&(e=void 0),{value:e&&e[a++],done:!e}}}};define(["require","exports","./Enum/Severity","jquery","./Icons","./Wizard"],function(e,t,a,n,o,l){"use strict";return new(function(){function e(){var e=this;this.triggerButton=".t3js-localize",this.localizationMode=null,this.sourceLanguage=null,this.records=[],n(function(){e.initialize()})}return e.prototype.initialize=function(){var e=this,t=this;o.getIcon("actions-localize",o.sizes.large).done(function(i){o.getIcon("actions-edit-copy",o.sizes.large).done(function(c){n(t.triggerButton).removeClass("disabled"),n(document).on("click",t.triggerButton,function(t){t.preventDefault();var r=n(t.currentTarget),d=[],s="";r.data("allowTranslate")&&d.push('<div class="row"><div class="btn-group col-sm-3"><label class="btn btn-block btn-default t3js-localization-option" data-helptext=".t3js-helptext-translate">'+i+'<input type="radio" name="mode" id="mode_translate" value="localize" style="display: none"><br>Translate</label></div><div class="col-sm-9"><p class="t3js-helptext t3js-helptext-translate text-muted">'+TYPO3.lang["localize.educate.translate"]+"</p></div></div>"),r.data("allowCopy")&&d.push('<div class="row"><div class="col-sm-3 btn-group"><label class="btn btn-block btn-default t3js-localization-option" data-helptext=".t3js-helptext-copy">'+c+'<input type="radio" name="mode" id="mode_copy" value="copyFromLanguage" style="display: none"><br>Copy</label></div><div class="col-sm-9"><p class="t3js-helptext t3js-helptext-copy text-muted">'+TYPO3.lang["localize.educate.copy"]+"</p></div></div>"),s+='<div data-toggle="buttons">'+d.join("<hr>")+"</div>",l.addSlide("localize-choose-action",TYPO3.lang["localize.wizard.header_page"].replace("{0}",r.data("page")).replace("{1}",r.data("languageName")),s,a.SeverityEnum.info),l.addSlide("localize-choose-language",TYPO3.lang["localize.view.chooseLanguage"],"",a.SeverityEnum.info,function(t){o.getIcon("spinner-circle-dark",o.sizes.large).done(function(a){t.html('<div class="text-center">'+a+"</div>"),e.loadAvailableLanguages(parseInt(r.data("pageId"),10),parseInt(r.data("languageId"),10)).done(function(a){if(1===a.length)return e.sourceLanguage=a[0].uid,void l.unlockNextStep().trigger("click");l.getComponent().on("click",".t3js-language-option",function(t){var a=n(t.currentTarget).find('input[type="radio"]');e.sourceLanguage=a.val(),console.log("Localization.ts@132",e.sourceLanguage),l.unlockNextStep()});var o,i,c=n("<div />",{class:"row","data-toggle":"buttons"});try{for(var r=__values(a),d=r.next();!d.done;d=r.next()){var s=d.value;c.append(n("<div />",{class:"col-sm-4"}).append(n("<label />",{class:"btn btn-default btn-block t3js-language-option option"}).text(" "+s.title).prepend(s.flagIcon).prepend(n("<input />",{type:"radio",name:"language",id:"language"+s.uid,value:s.uid,style:"display: none;"}))))}}catch(e){o={error:e}}finally{try{d&&!d.done&&(i=r.return)&&i.call(r)}finally{if(o)throw o.error}}t.empty().append(c)})})}),l.addSlide("localize-summary",TYPO3.lang["localize.view.summary"],"",a.SeverityEnum.info,function(t){o.getIcon("spinner-circle-dark",o.sizes.large).done(function(e){t.html('<div class="text-center">'+e+"</div>")}),e.getSummary(parseInt(r.data("pageId"),10),parseInt(r.data("languageId"),10)).done(function(a){t.empty(),e.records=[];var o=a.columns.columns;a.columns.columnList.forEach(function(l){if(void 0!==a.records[l]){var i=o[l],c=n("<div />",{class:"row"});a.records[l].forEach(function(t){var a=" ("+t.uid+") "+t.title;e.records.push(t.uid),c.append(n("<div />",{class:"col-sm-6"}).append(n("<div />",{class:"input-group"}).append(n("<span />",{class:"input-group-addon"}).append(n("<input />",{type:"checkbox",class:"t3js-localization-toggle-record",id:"record-uid-"+t.uid,checked:"checked","data-uid":t.uid,"aria-label":a})),n("<label />",{class:"form-control",for:"record-uid-"+t.uid}).text(a).prepend(t.icon))))}),t.append(n("<fieldset />",{class:"localization-fieldset"}).append(n("<label />").text(i).prepend(n("<input />",{class:"t3js-localization-toggle-column",type:"checkbox",checked:"checked"})),c))}}),l.unlockNextStep(),l.getComponent().on("change",".t3js-localization-toggle-record",function(t){var a=n(t.currentTarget),o=a.data("uid"),i=a.closest("fieldset"),c=i.find(".t3js-localization-toggle-column");if(a.is(":checked"))e.records.push(o);else{var r=e.records.indexOf(o);r>-1&&e.records.splice(r,1)}var d=i.find(".t3js-localization-toggle-record"),s=i.find(".t3js-localization-toggle-record:checked");c.prop("checked",s.length>0),c.prop("indeterminate",s.length>0&&s.length<d.length),e.records.length>0?l.unlockNextStep():l.lockNextStep()}).on("change",".t3js-localization-toggle-column",function(e){var t=n(e.currentTarget),a=t.closest("fieldset").find(".t3js-localization-toggle-record");a.prop("checked",t.is(":checked")),a.trigger("change")})})}),l.addFinalProcessingSlide(function(){e.localizeRecords(parseInt(r.data("pageId"),10),parseInt(r.data("languageId"),10),e.records).done(function(){l.dismiss(),document.location.reload()})}).done(function(){l.show(),l.getComponent().on("click",".t3js-localization-option",function(t){var a=n(t.currentTarget),o=a.find('input[type="radio"]');if(a.data("helptext")){var i=n(t.delegateTarget);i.find(".t3js-helptext").addClass("text-muted"),i.find(a.data("helptext")).removeClass("text-muted")}e.localizationMode=o.val(),l.unlockNextStep()})})})})})},e.prototype.loadAvailableLanguages=function(e,t){return n.ajax({url:TYPO3.settings.ajaxUrls.page_languages,data:{pageId:e,languageId:t}})},e.prototype.getSummary=function(e,t){return n.ajax({url:TYPO3.settings.ajaxUrls.records_localize_summary,data:{pageId:e,destLanguageId:t,languageId:this.sourceLanguage}})},e.prototype.localizeRecords=function(e,t,a){return n.ajax({url:TYPO3.settings.ajaxUrls.records_localize,data:{pageId:e,srcLanguageId:this.sourceLanguage,destLanguageId:t,action:this.localizationMode,uidList:a}})},e}())});
\ No newline at end of file
index bbb7fc5..422b1bd 100644 (file)
  *
  * The TYPO3 project - inspiring people to share!
  */
-
-/**
- * Module: TYPO3/CMS/Backend/Wizard
- * API for wizard windows.
- */
-define(['jquery',
-  'TYPO3/CMS/Backend/Modal',
-  'TYPO3/CMS/Backend/Severity',
-  'TYPO3/CMS/Backend/Icons',
-  'bootstrap'
-], function($, Modal, Severity, Icons) {
-  'use strict';
-
-  try {
-    // fetch from parent
-    if (parent && parent.window.TYPO3 && parent.window.TYPO3.Wizard) {
-      return parent.window.TYPO3.Wizard;
-    }
-
-    // fetch object from outer frame
-    if (top && top.TYPO3 && top.TYPO3.Wizard) {
-      return top.TYPO3.Wizard;
-    }
-  } catch (e) {
-    // This only happens if the opener, parent or top is some other url (eg a local file)
-    // which loaded the current window. Then the browser's cross domain policy jumps in
-    // and raises an exception.
-    // For this case we are safe and we can create our global object below.
-  }
-
-  /**
-   * @type {{setup: {slides: Array, settings: {}, forceSelection: boolean, $carousel: null}, originalSetup: {}}}
-   * @exports TYPO3/CMS/Backend/Wizard
-   */
-  var Wizard = {
-    setup: {
-      slides: [],
-      settings: {},
-      forceSelection: true,
-      $carousel: null
-    },
-    originalSetup: {}
-  };
-
-  /**
-   * Initializes the events after building the wizards
-   *
-   * @private
-   */
-  Wizard.initializeEvents = function() {
-    var $modal = Wizard.setup.$carousel.closest('.modal'),
-      $modalTitle = $modal.find('.modal-title'),
-      $modalFooter = $modal.find('.modal-footer'),
-      $nextButton = $modalFooter.find('button[name="next"]');
-
-    $nextButton.on('click', function() {
-      Wizard.setup.$carousel.carousel('next');
-    });
-
-    Wizard.setup.$carousel.on('slide.bs.carousel', function() {
-      var nextSlideNumber = Wizard.setup.$carousel.data('currentSlide') + 1,
-        currentIndex = Wizard.setup.$carousel.data('currentIndex') + 1;
-
-      $modalTitle.text(Wizard.setup.slides[currentIndex].title);
-
-      Wizard.setup.$carousel.data('currentSlide', nextSlideNumber);
-      Wizard.setup.$carousel.data('currentIndex', currentIndex);
-
-      if (nextSlideNumber >= Wizard.setup.$carousel.data('realSlideCount')) {
-        // Point of no return - hide modal footer disable any closing ability
-        $modal.find('.modal-header .close').remove();
-        $modalFooter.slideUp();
-      } else {
-        $modalFooter.find('.progress-bar')
-          .width(Wizard.setup.$carousel.data('initialStep') * nextSlideNumber + '%')
-          .text(top.TYPO3.lang['wizard.progress']
-            .replace('{0}', nextSlideNumber)
-            .replace('{1}', Wizard.setup.$carousel.data('slideCount')));
-      }
-
-      $nextButton
-        .removeClass('btn-' + Severity.getCssClass(Wizard.setup.slides[currentIndex - 1].severity))
-        .addClass('btn-' + Severity.getCssClass(Wizard.setup.slides[currentIndex].severity));
-
-      $modal
-        .removeClass('modal-severity-' + Severity.getCssClass(Wizard.setup.slides[currentIndex - 1].severity))
-        .addClass('modal-severity-' + Severity.getCssClass(Wizard.setup.slides[currentIndex].severity));
-    }).on('slid.bs.carousel', function(e) {
-      var currentIndex = Wizard.setup.$carousel.data('currentIndex'),
-        slide = Wizard.setup.slides[currentIndex];
-
-      Wizard.runSlideCallback(slide, $(e.relatedTarget));
-
-      if (Wizard.setup.forceSelection) {
-        Wizard.lockNextStep();
-      }
-    });
-
-    /**
-     * Custom event, closes the wizard
-     */
-    var cmp = Wizard.getComponent();
-    cmp.on('wizard-dismiss', Wizard.dismiss);
-
-    Modal.currentModal.on('hidden.bs.modal', function() {
-      cmp.trigger('wizard-dismissed');
-    }).on('shown.bs.modal', function() {
-      cmp.trigger('wizard-visible');
-    });
-  };
-
-  /**
-   * @param {String} key
-   * @param {*} value
-   * @returns {Object}
-   */
-  Wizard.set = function(key, value) {
-    Wizard.setup.settings[key] = value;
-    return Wizard;
-  };
-
-  /**
-   * Adds a new slide to the wizard
-   *
-   * @param {String} identifier
-   * @param {String} title
-   * @param {String} content
-   * @param {String} severity
-   * @param {Function} callback
-   * @returns {Object}
-   */
-  Wizard.addSlide = function(identifier, title, content, severity, callback) {
-    Wizard.setup.slides.push({
-      identifier: identifier,
-      title: title,
-      content: content || '',
-      severity: (typeof severity !== 'undefined' ? severity : Severity.info),
-      callback: callback
-    });
-
-    return Wizard;
-  };
-
-  /**
-   * Adds a final processing slide
-   *
-   * @param {Function} callback
-   * @returns {Object}
-   */
-  Wizard.addFinalProcessingSlide = function(callback) {
-    if (typeof callback !== 'function') {
-      callback = function() {
-        Wizard.dismiss();
-      }
-    }
-
-    return Icons.getIcon('spinner-circle-dark', Icons.sizes.large, null, null).done(function(markup) {
-      var $processingSlide = $('<div />', {class: 'text-center'}).append(markup);
-      Wizard.addSlide(
-        'final-processing-slide', top.TYPO3.lang['wizard.processing.title'],
-        $processingSlide[0].outerHTML,
-        Severity.info,
-        callback
-      );
-    });
-  };
-
-  /**
-   * Processes the footer of the modal
-   *
-   * @private
-   */
-  Wizard.addProgressBar = function() {
-    var realSlideCount = Wizard.setup.$carousel.find('.item').length,
-      slideCount = Math.max(1, realSlideCount),
-      initialStep,
-      $modal = Wizard.setup.$carousel.closest('.modal'),
-      $modalFooter = $modal.find('.modal-footer');
-
-    initialStep = Math.round(100 / slideCount);
-
-    Wizard.setup.$carousel
-      .data('initialStep', initialStep)
-      .data('slideCount', slideCount)
-      .data('realSlideCount', realSlideCount)
-      .data('currentIndex', 0)
-      .data('currentSlide', 1);
-
-    // Append progress bar to modal footer
-    if (slideCount > 1) {
-      $modalFooter.prepend(
-        $('<div />', {class: 'progress'}).append(
-          $('<div />', {
-            role: 'progressbar',
-            class: 'progress-bar',
-            'aria-valuemin': 0,
-            'aria-valuenow': initialStep,
-            'aria-valuemax': 100
-          }).width(initialStep + '%').text(
-            top.TYPO3.lang['wizard.progress']
-              .replace('{0}', '1')
-              .replace('{1}', slideCount)
-          )
-        )
-      );
-    }
-  };
-
-  /**
-   * Generates the markup of slides added by addSlide()
-   *
-   * @returns {$}
-   * @private
-   */
-  Wizard.generateSlides = function() {
-    // Check whether the slides were already generated
-    if (Wizard.setup.$carousel !== null) {
-      return Wizard.setup.$carousel;
-    }
-
-    var slides =
-      '<div class="carousel slide" data-ride="carousel" data-interval="false">'
-      + '<div class="carousel-inner" role="listbox">';
-
-    for (var i = 0; i < Wizard.setup.slides.length; ++i) {
-      var currentSlide = Wizard.setup.slides[i],
-        slideContent = currentSlide.content;
-
-      if (typeof slideContent === 'object') {
-        slideContent = slideContent.html();
-      }
-      slides += '<div class="item" data-slide="' + currentSlide.identifier + '">' + slideContent + '</div>';
-    }
-
-    slides += '</div></div>';
-
-    Wizard.setup.$carousel = $(slides);
-    Wizard.setup.$carousel.find('.item').first().addClass('active');
-
-    return Wizard.setup.$carousel;
-  };
-
-  /**
-   * Renders the wizard
-   *
-   * @returns {$}
-   */
-  Wizard.show = function() {
-    var $slides = Wizard.generateSlides(),
-      firstSlide = Wizard.setup.slides[0];
-
-    var $modal = Modal.confirm(
-      firstSlide.title,
-      $slides,
-      firstSlide.severity,
-      [{
-        text: top.TYPO3.lang['wizard.button.cancel'],
-        active: true,
-        btnClass: 'btn-default',
-        name: 'cancel',
-        trigger: function() {
-          Wizard.getComponent().trigger('wizard-dismiss');
-        }
-      }, {
-        text: top.TYPO3.lang['wizard.button.next'],
-        btnClass: 'btn-' + Severity.getCssClass(firstSlide.severity),
-        name: 'next'
-      }]
-    );
-
-    if (Wizard.setup.forceSelection) {
-      Wizard.lockNextStep();
-    }
-
-    Wizard.addProgressBar($modal);
-    Wizard.initializeEvents();
-
-    Wizard.getComponent().on('wizard-visible', function() {
-      Wizard.runSlideCallback(firstSlide, Wizard.setup.$carousel.find('.item').first());
-    }).on('wizard-dismissed', function() {
-      Wizard.setup = $.extend(true, {}, Wizard.originalSetup);
-    });
-  };
-
-  /**
-   * Runs the callback for the given slide
-   *
-   * @param {Object} slide
-   * @param {$} $slide
-   * @private
-   */
-  Wizard.runSlideCallback = function(slide, $slide) {
-    if (typeof slide.callback === 'function') {
-      slide.callback($slide, Wizard.setup.settings, slide.identifier);
-    }
-  };
-
-  /**
-   * Get the wizard component
-   *
-   * @returns {$}
-   */
-  Wizard.getComponent = function() {
-    if (Wizard.setup.$carousel === null) {
-      Wizard.generateSlides();
-    }
-    return Wizard.setup.$carousel;
-  };
-
-  /**
-   * Closes the wizard window
-   */
-  Wizard.dismiss = function() {
-    Modal.dismiss();
-  };
-
-  /**
-   * Locks the button for continuing to the next step
-   *
-   * @returns {$}
-   */
-  Wizard.lockNextStep = function() {
-    var $button = Wizard.setup.$carousel.closest('.modal').find('button[name="next"]');
-    $button.prop('disabled', true);
-
-    return $button;
-  };
-
-  /**
-   * Unlocks the button for continuing to the next step
-   *
-   * @returns {$}
-   */
-  Wizard.unlockNextStep = function() {
-    var $button = Wizard.setup.$carousel.closest('.modal').find('button[name="next"]');
-    $button.prop('disabled', false);
-
-    return $button;
-  };
-
-  // Store the initial setup
-  Wizard.originalSetup = $.extend(true, {}, Wizard.setup);
-
-  // expose as global object
-  TYPO3.Wizard = Wizard;
-
-  return Wizard;
-});
+define(["require","exports","./Enum/Severity","jquery","./Modal","./Severity","./Icons"],function(e,t,s,i,r,n,a){"use strict";var o,l=function(){function e(){this.setup={slides:[],settings:{},forceSelection:!0,$carousel:null},this.originalSetup=i.extend(!0,{},this.setup)}return e.prototype.set=function(e,t){return this.setup.settings[e]=t,this},e.prototype.addSlide=function(e,t,i,r,n){void 0===i&&(i=""),void 0===r&&(r=s.SeverityEnum.info);var a={identifier:e,title:t,content:i,severity:r,callback:n};return this.setup.slides.push(a),this},e.prototype.addFinalProcessingSlide=function(e){var t=this;return e||(e=function(){t.dismiss()}),a.getIcon("spinner-circle-dark",a.sizes.large,null,null).done(function(s){var r=i("<div />",{class:"text-center"}).append(s);t.addSlide("final-processing-slide",top.TYPO3.lang["wizard.processing.title"],r[0].outerHTML,n.info,e)})},e.prototype.show=function(){var e=this,t=this.generateSlides(),s=this.setup.slides[0];r.confirm(s.title,t,s.severity,[{text:top.TYPO3.lang["wizard.button.cancel"],active:!0,btnClass:"btn-default",name:"cancel",trigger:function(){e.getComponent().trigger("wizard-dismiss")}},{text:top.TYPO3.lang["wizard.button.next"],btnClass:"btn-"+n.getCssClass(s.severity),name:"next"}]),this.setup.forceSelection&&this.lockNextStep(),this.addProgressBar(),this.initializeEvents(),this.getComponent().on("wizard-visible",function(){e.runSlideCallback(s,e.setup.$carousel.find(".item").first())}).on("wizard-dismissed",function(){e.setup=i.extend(!0,{},e.originalSetup)})},e.prototype.getComponent=function(){return null===this.setup.$carousel&&this.generateSlides(),this.setup.$carousel},e.prototype.dismiss=function(){r.dismiss()},e.prototype.lockNextStep=function(){var e=this.setup.$carousel.closest(".modal").find('button[name="next"]');return e.prop("disabled",!0),e},e.prototype.unlockNextStep=function(){var e=this.setup.$carousel.closest(".modal").find('button[name="next"]');return e.prop("disabled",!1),e},e.prototype.initializeEvents=function(){var e=this,t=this.setup.$carousel.closest(".modal"),s=t.find(".modal-title"),a=t.find(".modal-footer"),o=a.find('button[name="next"]');o.on("click",function(){e.setup.$carousel.carousel("next")}),this.setup.$carousel.on("slide.bs.carousel",function(){var i=e.setup.$carousel.data("currentSlide")+1,r=e.setup.$carousel.data("currentIndex")+1;s.text(e.setup.slides[r].title),e.setup.$carousel.data("currentSlide",i),e.setup.$carousel.data("currentIndex",r),i>=e.setup.$carousel.data("realSlideCount")?(t.find(".modal-header .close").remove(),a.slideUp()):a.find(".progress-bar").width(e.setup.$carousel.data("initialStep")*i+"%").text(top.TYPO3.lang["wizard.progress"].replace("{0}",i).replace("{1}",e.setup.$carousel.data("slideCount"))),o.removeClass("btn-"+n.getCssClass(e.setup.slides[r-1].severity)).addClass("btn-"+n.getCssClass(e.setup.slides[r].severity)),t.removeClass("modal-severity-"+n.getCssClass(e.setup.slides[r-1].severity)).addClass("modal-severity-"+n.getCssClass(e.setup.slides[r].severity))}).on("slid.bs.carousel",function(t){var s=e.setup.$carousel.data("currentIndex"),r=e.setup.slides[s];e.runSlideCallback(r,i(t.relatedTarget)),e.setup.forceSelection&&e.lockNextStep()});var l=this.getComponent();l.on("wizard-dismiss",this.dismiss),r.currentModal.on("hidden.bs.modal",function(){l.trigger("wizard-dismissed")}).on("shown.bs.modal",function(){l.trigger("wizard-visible")})},e.prototype.runSlideCallback=function(e,t){"function"==typeof e.callback&&e.callback(t,this.setup.settings,e.identifier)},e.prototype.addProgressBar=function(){var e,t=this.setup.$carousel.find(".item").length,s=Math.max(1,t),r=this.setup.$carousel.closest(".modal").find(".modal-footer");e=Math.round(100/s),this.setup.$carousel.data("initialStep",e).data("slideCount",s).data("realSlideCount",t).data("currentIndex",0).data("currentSlide",1),s>1&&r.prepend(i("<div />",{class:"progress"}).append(i("<div />",{role:"progressbar",class:"progress-bar","aria-valuemin":0,"aria-valuenow":e,"aria-valuemax":100}).width(e+"%").text(top.TYPO3.lang["wizard.progress"].replace("{0}","1").replace("{1}",s))))},e.prototype.generateSlides=function(){if(null!==this.setup.$carousel)return this.setup.$carousel;for(var e='<div class="carousel slide" data-ride="carousel" data-interval="false"><div class="carousel-inner" role="listbox">',t=0;t<this.setup.slides.length;++t){var s=this.setup.slides[t],r=s.content;"object"==typeof r&&(r=r.html()),e+='<div class="item" data-slide="'+s.identifier+'">'+r+"</div>"}return e+="</div></div>",this.setup.$carousel=i(e),this.setup.$carousel.find(".item").first().addClass("active"),this.setup.$carousel},e}();try{window.opener&&window.opener.TYPO3&&window.opener.TYPO3.Wizard&&(o=window.opener.TYPO3.Wizard),parent&&parent.window.TYPO3&&parent.window.TYPO3.Wizard&&(o=parent.window.TYPO3.Wizard),top&&top.TYPO3&&top.TYPO3.Wizard&&(o=top.TYPO3.Wizard)}catch(e){}return o||(o=new l,"undefined"!=typeof TYPO3&&(TYPO3.Wizard=o)),o});
\ No newline at end of file