Advertisement
Guest User

Chevereto PUP without its closure

a guest
Apr 19th, 2019
388
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* --------------------------------------------------------------------
  2.  
  3.   Chevereto Popup Upload Plugin (PUP)
  4.  
  5.   @website  http://chevereto.com/
  6.   @version  1.0.6
  7.   @author   Rodolfo Berrios A. <http://rodolfoberrios.com/>
  8.  
  9.   --------------------------------------------------------------------- */
  10.  
  11. var PUP = {
  12.   defaultSettings: {
  13.     url: 'https://demo.chevereto.com/upload',
  14.     vendor: 'auto',
  15.     mode: 'auto',
  16.     lang: 'auto',
  17.     autoInsert: 'bbcode-embed-medium',
  18.     palette: 'default',
  19.     init: 'onload',
  20.     containerClass: 1,
  21.     buttonClass: 1,
  22.     sibling: 0,
  23.     siblingPos: 'after',
  24.     fitEditor: 0,
  25.     observe: 0,
  26.     observeCache: 1,
  27.     html: '<div class="%cClass"><button %x class="%bClass"><span class="%iClass">%iconSvg</span><span class="%tClass">%text</span></button></div>',
  28.     css: '.%cClass{display:inline-block;margin-top:5px;margin-bottom:5px}.%bClass{line-height:normal;-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s;outline:0;color:%2;border:none;cursor:pointer;border:1px solid rgba(0,0,0,.15);background:%1;border-radius:.2em;padding:.5em 1em;font-size:12px;font-weight:700;text-shadow:none}.%bClass:hover{background:%3;color:%4;border-color:rgba(0,0,0,.1)}.%iClass,.%tClass{display:inline-block;vertical-align:middle}.%iClass svg{display:block;width:1em;height:1em;fill:currentColor}.%tClass{margin-left:.25em}',
  29.   },
  30.   ns: {
  31.     plugin: 'chevereto-pup'
  32.   },
  33.   palettes: {
  34.     default: ['#ececec','#333','#2980b9','#fff'],
  35.     clear: ['inherit','inherit','inherit','#2980b9'],
  36.     turquoise: ['#16a085','#fff','#1abc9c','#fff'],
  37.     green: ['#27ae60','#fff','#2ecc71','#fff'],
  38.     blue: ['#2980b9','#fff','#3498db','#fff'],
  39.     purple: ['#8e44ad','#fff','#9b59b6','#fff'],
  40.     darkblue: ['#2c3e50','#fff','#34495e','#fff'],
  41.     yellow: ['#f39c12','#fff','#f1c40f','#fff'],
  42.     orange: ['#d35400','#fff','#e67e22','#fff'],
  43.     red: ['#c0392b','#fff','#e74c3c','#fff'],
  44.     grey: ['#ececec','#000','#e0e0e0','#000'],
  45.     black: ['#333','#fff','#666','#fff']
  46.   },
  47.   classProps: ['button', 'container'],
  48.   iconSvg: '<svg class="%iClass" xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M76.7 87.5c12.8 0 23.3-13.3 23.3-29.4 0-13.6-5.2-25.7-15.4-27.5 0 0-3.5-0.7-5.6 1.7 0 0 0.6 9.4-2.9 12.6 0 0 8.7-32.4-23.7-32.4 -29.3 0-22.5 34.5-22.5 34.5 -5-6.4-0.6-19.6-0.6-19.6 -2.5-2.6-6.1-2.5-6.1-2.5C10.9 25 0 39.1 0 54.6c0 15.5 9.3 32.7 29.3 32.7 2 0 6.4 0 11.7 0V68.5h-13l22-22 22 22H59v18.8C68.6 87.4 76.7 87.5 76.7 87.5z"/></svg>',
  49.   l10n: {
  50.     ar:"\u062a\u062d\u0645\u064a\u0644 \u0627\u0644\u0635\u0648\u0631",
  51.     cs:"Nahr\u00e1t obr\u00e1zky",
  52.     da:"Upload billeder",
  53.     de:"Bilder hochladen",
  54.     es:"Subir im\u00e1genes",
  55.     fi:"Lataa kuvia",
  56.     fr:"Importer des images",
  57.     id:"Unggah gambar",
  58.     it:"Carica immagini",
  59.     ja:"\u753b\u50cf\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9",
  60.     nb:"Last opp bilder",
  61.     nl:"Upload afbeeldingen",
  62.     pl:"Wy\u015Blij obrazy",
  63.     pt_BR:"Enviar imagens",
  64.     ru:"\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f",
  65.     tr:"Resim Yukle",
  66.     uk:"\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u043D\u044F",
  67.     zh_CN:"\u4e0a\u4f20\u56fe\u7247",
  68.     zh_TW:"\u4e0a\u50b3\u5716\u7247"
  69.   },
  70.   vendors: {
  71.     default: {
  72.       check: function() {
  73.         return 1;
  74.       },
  75.       getEditor: function() {
  76.         var skip = {
  77.           textarea: {
  78.             name: ['recaptcha', 'search', 'recipients', 'coppa', '^comment_list', 'username_list', 'add']
  79.           },
  80.           ce: {
  81.             dataset: ['gramm']
  82.           }
  83.         };
  84.         var mods = ['~', '|', '^', '$', '*'];
  85.         var not = {};
  86.         for(var k in skip) {
  87.           not[k] = '';
  88.           var el = skip[k];
  89.           for(var attr in el) {
  90.             for (var i=0; i<el[attr].length; i++) {
  91.               var mod = '';
  92.               var value = el[attr][i];
  93.               var f = value.charAt(0);
  94.               if(mods.indexOf(f) > -1) {
  95.                 mod = f;
  96.                 value = value.substring(1);
  97.               }
  98.               not[k] += ':not([' + (attr == 'dataset' ? ('data-' + value) : (attr + mod + '="' + value + '"')) + '])';
  99.             }
  100.           }
  101.         }
  102.         return document.querySelectorAll('[contenteditable=""]' + not.ce + ',[contenteditable="true"]' + not.ce + ',textarea:not([readonly])' + not.textarea);
  103.       }
  104.     },
  105.     bbpress: {
  106.       settings: {
  107.         autoInsert: 'html-embed-medium',
  108.         html: '<input %x type="button" class="ed_button button button-small" aria-label="%text" value="%text">',
  109.         sibling: '#qt_bbp_reply_content_img',
  110.         siblingPos: 'before'
  111.       },
  112.       check: 'bbpEngagementJS',
  113.     },
  114.     discourse: {
  115.       settings: {
  116.         autoInsert: 'markdown-embed-medium',
  117.         html: '<button %x title="%text" class="upload btn no-text btn-icon ember-view"><i class="fa fa-cloud-upload d-icon d-icon-upload"></i></button>',
  118.         sibling: '.upload.btn',
  119.         siblingPos: 'before',
  120.         observe: '.create,#create-topic,.usercard-controls button',
  121.         observeCache: 0,
  122.         onDemand: 1
  123.       },
  124.       check: 'Discourse'
  125.     },
  126.     discuz: {
  127.       settings: {
  128.         buttonClass: 1,
  129.         html: '<a %x title="%text" class="%bClass">%iconSvg</a>',
  130.         sibling: '.fclr,#e_attach',
  131.         css: 'a.%bClass,.bar a.%bClass{box-sizing:border-box;cursor:pointer;background:%1;color:%2;text-indent:unset;position:relative}.b1r a.%bClass:hover,a.%bClass:hover{background:%3;color:%4}a.%bClass{font-size:14px}.b1r a.%bClass{border:1px solid rgba(0,0,0,.15)!important;font-size:20px;padding:0;height:44px}.%bClass svg{font-size:1em;width:1em;height:1em;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;left:50%;top:50%;fill:currentColor}',
  132.         palette: 'purple',
  133.       },
  134.       palettes: {
  135.         default: ['transparent','#333','#2980b9','#fff'],
  136.       },
  137.       check: 'DISCUZCODE',
  138.       getEditor: function() {
  139.         return document.querySelector('.area textarea[name="message"]');
  140.       }
  141.     },
  142.     ipb: {
  143.       settings: {
  144.         autoInsert: 'html-embed-medium',
  145.         html: '<a %x class="cke_button cke_button_off %bClass" title="%text" tabindex="-1" hidefocus="true" role="button"><span class="cke_button_icon">%iconSvg</span><span class="cke_button_label" aria-hidden="false">%text</span><span class="cke_button_label" aria-hidden="false"></span></a>',
  146.         sibling: '.cke_button__ipslink',
  147.         siblingPos: 'before',
  148.         css: '.cke_button.%bClass{background:%1;position:relative}.cke_button.%bClass:hover{background:%3;border-color:%5}.cke_button.%bClass svg{font-size:15px;width:1em;height:1em;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;left:50%;top:50%;fill:%2}.cke_button.%bClass:hover svg{fill:%4}'
  149.       },
  150.       palettes: {
  151.         default: ['inherit', '#444', '', 'inherit']
  152.       },
  153.       check: 'ips',
  154.       getEditorFn: function() {
  155.         var id = this.getEditor().dataset.ipseditorName;
  156.         return CKEDITOR.instances[id];
  157.       },
  158.       getEditor: function() {
  159.         return document.querySelector('[data-ipseditor-name]');
  160.       },
  161.       editorValue: function(str) {
  162.         var element = CKEDITOR.dom.element.createFromHtml('<p>' + str + '</p>');
  163.         this.getEditorFn().insertElement(element);
  164.       },
  165.       useCustomEditor: function() {
  166.         return 1;
  167.       }
  168.     },
  169.     mybb: {
  170.       settings: {
  171.         sibling: '#quickreply_e > tr > td > *:last-child, .sceditor-container',
  172.         fitEditor: 0,
  173.         extracss: '.trow2 .%cClass{margin-bottom:0}'
  174.       },
  175.       check: 'MyBB',
  176.       getEditor: function() {
  177.         if(MyBBEditor) {
  178.           return MyBBEditor.getContentAreaContainer()[0].parentElement;
  179.         }
  180.         return document.querySelector('#quickreply_e textarea');
  181.       },
  182.       editorValue: function(str) {
  183.         if(MyBBEditor) {
  184.           var fn = MyBBEditor.inSourceMode() ? 'insert' : 'wysiwygEditorInsertHtml';
  185.           MyBBEditor[fn](fn == 'insert' ? str : MyBBEditor.fromBBCode(str));
  186.         } else {
  187.           this.getEditor().value += str;
  188.         }
  189.       },
  190.       useCustomEditor: function() {
  191.         return !!MyBBEditor;
  192.       }
  193.     },
  194.     nodebb: {
  195.       settings: {
  196.         autoInsert: 'markdown-embed-medium',
  197.         html: '<li %x tabindex="-1" title="%text"><i class="fa fa-cloud-upload"></i></li>',
  198.         sibling: '[data-format="picture-o"]',
  199.         siblingPos: 'before',
  200.         observe: '[component="category/post"],[component="topic/reply"],[component="topic/reply-as-topic"],[component="post/reply"],[component="post/quote"]',
  201.         observeCache: 0,
  202.         onDemand: 1
  203.       },
  204.       check: '__nodebbSpamBeGoneCreateCaptcha__',
  205.       callback: function() {
  206.         var els = document.querySelectorAll('.btn-toolbar .img-upload-btn');
  207.         for(var i=0; i<els.length; i++) {
  208.           els[i].parentNode.removeChild(els[i]);
  209.         }
  210.       }
  211.     },
  212.     phpbb: {
  213.       settings: {
  214.         html: (document.querySelector('#format-buttons *:first-child') && document.querySelector('#format-buttons *:first-child').tagName == 'BUTTON') ? ' <button %x type="button" class="button button-icon-only" title="%text"><i class="icon fa-cloud-upload fa-fw" aria-hidden="true"></i></button> ' : ' <input %x type="button" class="button2" value="%text"> ',
  215.         sibling: '.bbcode-img',
  216.         siblingPos: 'before'
  217.       },
  218.       check: 'phpbb',
  219.       getEditor: function() {
  220.         if(typeof form_name == typeof undefined || typeof text_name == typeof undefined) {
  221.           return;
  222.         }
  223.         return document.forms[form_name].elements[text_name];
  224.       },
  225.     },
  226.     redactor2: {
  227.       getEditor: function() {
  228.         var editor = this.getEditorFn();
  229.         if(!editor) {
  230.           return null
  231.         };
  232.         return !this.useCustomEditor() ? editor[0] : editor.$box[0];
  233.       },
  234.       getEditorEl: function() {
  235.         return this.useCustomEditor() ? this.getEditorFn().$editor[0] : this.getEditorFn()[0];
  236.       },
  237.       editorValue: function(str) {
  238.         var nl = '<p><br></p>';
  239.         var property = this.useCustomEditor() ? 'innerHTML' : 'value';
  240.         if(typeof str == 'string') {
  241.           if(this.useCustomEditor()) {
  242.             var insert = '<p>' + str + '</p>';
  243.             this.getEditorFn().insert.html(this.editorValue() !== '' ? (nl + insert) : insert);
  244.           } else {
  245.             this.getEditorEl()[property] = str;
  246.           }
  247.           return;
  248.         }
  249.         var value = this.getEditorEl()[property];
  250.         if(this.useCustomEditor() && value == '<p><br></p>') {
  251.           return '';
  252.         }
  253.         return this.getEditorEl()[property];
  254.       },
  255.       useCustomEditor: function() {
  256.         return !(this.getEditorFn() instanceof jQuery);
  257.       }
  258.     },
  259.     smf: {
  260.       settings: {
  261.         html: ' <button %x title="%text" class="%bClass"><span class="%iClass">%iconSvg</span><span class="%tClass">%text</span></button> ',
  262.         css: '%defaultCSS #bbcBox_message .%bClass{margin-right:1px;transition:none;color:%2;padding:0;width:23px;height:21px;border-radius:5px;background-color:%1}#bbcBox_message .%bClass:hover{background-color:%3}#bbcBox_message .%tClass{display:none}',
  263.         sibling: '#BBCBox_message_button_1_1,.quickReplyContent + div',
  264.         siblingPos: 'before',
  265.         fitEditor: 1,
  266.       },
  267.       palettes: {
  268.         default: ['#E7E7E7', '#333', '#B0C4D6', '#333'],
  269.       },
  270.       check: 'smf_scripturl',
  271.       getEditor: function() {
  272.         return smf_editorArray.length > 0 ? smf_editorArray[0].oTextHandle : document.querySelector('.quickReplyContent textarea');
  273.       }
  274.     },
  275.     vanilla: {
  276.       settings: {
  277.         autoInsert: 'markdown-embed-medium',
  278.         html: '<span %x class="icon icon-cloud-upload" title="%text"></span>',
  279.         sibling: '.editor-dropdown-upload'
  280.       },
  281.       check: 'Vanilla',
  282.       getEditor: function() {
  283.         return document.getElementById('Form_Body');
  284.       }
  285.     },
  286.     vbulletin: {
  287.       settings: {
  288.         autoInsert: 'html-embed-medium',
  289.         html: '<li %x class="%bClass b-toolbar__item b-toolbar__item--secondary" title="%text" tabindex="0">%iconSvg</li>',
  290.         sibling: '.b-toolbar__item--secondary:first-child',
  291.         siblingPos: 'before',
  292.         css: '.%bClass{background:%1;color:%2;position:relative}.%bClass:hover{background:%3;color:%4;border-color:%5}.%bClass svg{font-size:15px;width:1em;height:1em;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;left:50%;top:50%;fill:currentColor}'
  293.       },
  294.       palettes: {
  295.         default: ['', '#4B6977', '', '#007EB8']
  296.       },
  297.       check: 'vBulletin',
  298.       getEditorFn: function() {
  299.         var id = this.getEditor().getAttribute('ck-editorid');
  300.         return CKEDITOR.instances[id];
  301.       },
  302.       getEditor: function() {
  303.         return document.querySelector('[data-message-type]');
  304.       },
  305.       editorValue: function(str) {
  306.         var element = CKEDITOR.dom.element.createFromHtml('<p>' + str + '</p>');
  307.         this.getEditorFn().insertElement(element);
  308.       },
  309.       useCustomEditor: function() {
  310.         return 1;
  311.       }
  312.     },
  313.     // Redactor
  314.     // At some point,
  315.     WoltLab: {
  316.       settings: {
  317.         autoInsert: 'html-embed-medium',
  318.         sibling: 'li[data-name="settings"]',
  319.         html: '<li %x><a><span class="icon icon16 fa-cloud-upload"></span> <span>%text</span></a></li>'
  320.       },
  321.       check: 'WBB',
  322.       getEditorFn: function() {
  323.         var redactor = $("#text").data('redactor');
  324.         if(redactor) {
  325.           return redactor;
  326.         }
  327.         return null;
  328.       },
  329.     },
  330.     // Redactor
  331.     XF1: {
  332.       settings: {
  333.         autoInsert: 'html-embed-medium',
  334.           containerClass: 1,
  335.           buttonClass: 1,
  336.         html: '<li class="%cClass"><a %x class="%bClass" unselectable="on" title="%text">%iconSvg</a></li>',
  337.           sibling: '.redactor_btn_container_image',
  338.         siblingPos: 'before',
  339.         css: 'li.%cClass .%bClass{background:%1;color:%2;text-indent:unset;border-radius:3px;position:relative}li.%cClass a.%bClass:hover{background:%3;color:%4;border-color:%5}.%cClass .%bClass svg{font-size:15px;width:1em;height:1em;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;left:50%;top:50%;fill:currentColor}',
  340.         observe: '.edit.OverlayTrigger',
  341.         observeCache: 1
  342.         },
  343.       palettes: {
  344.         default: ['none', 'inherit', 'none', 'inherit', '']
  345.       },
  346.       check: 'XenForo',
  347.       getEditorFn: function() {
  348.         var form = (document.querySelector('#exposeMask') && document.querySelector('#exposeMask').offsetParent) ? '.xenOverlay form' : 'form';
  349.         if(form !== 'form') {
  350.           var forms = document.querySelectorAll(form);
  351.           for(var i=0; i<forms.length; i++) {
  352.             if(forms[i].offsetParent) {
  353.               form += '[action="' + forms[i].getAttribute('action') + '"]';
  354.               break;
  355.             }
  356.           }
  357.         }
  358.         return XenForo.getEditorInForm(form);
  359.       },
  360.       getEditor: function() {
  361.         var editor = this.getEditorFn();
  362.         if(!editor) {
  363.           return null
  364.         };
  365.         return !this.useCustomEditor() ? editor[0] : editor.$box[0];
  366.       },
  367.       getEditorEl: function() {
  368.         return this.useCustomEditor() ? this.getEditorFn().$editor[0] : this.getEditorFn()[0];
  369.       },
  370.       editorValue: function(str) {
  371.         var nl = '<p><br></p>';
  372.         var property = this.useCustomEditor() ? 'innerHTML' : 'value';
  373.         if(typeof str == 'string') {
  374.           if(this.useCustomEditor()) {
  375.             var insert = '<p>' + str + '</p>';
  376.             this.getEditorFn().insertHtml(this.editorValue() !== '' ? (nl + insert) : insert);
  377.           } else {
  378.             this.getEditorEl()[property] = str;
  379.           }
  380.           return;
  381.         }
  382.         var value = this.getEditorEl()[property];
  383.         if(this.useCustomEditor() && value == '<p><br></p>') {
  384.           return '';
  385.         }
  386.         return this.getEditorEl()[property];
  387.       },
  388.       useCustomEditor: function() {
  389.         return !(this.getEditorFn() instanceof jQuery);
  390.       }
  391.     },
  392.     // Froala
  393.     XF2: {
  394.       // I left commented the stuff needed for making this work inside froala toolbar, but on window resize it will revert your sibling element pos. Is just a limitation of this kind of implementation
  395.       settings: {
  396.         autoInsert: 'html-embed-medium',
  397.         containerClass: 1,
  398.         buttonClass: 1,
  399.         // html: '<div class="%cClass"><button type="button" tabindex="-1" role="button" title="%text" class="%bClass fr-command fr-btn fr-btn-font_awesome" data-cmd="PUP" %x><i class="fa fa-cloud-upload" aria-hidden="true"></i><span class="fr-sr-only">%text</span></button></div>',
  400.         html: ' <a %x class="%bClass button button--link button button--icon button--icon--upload"><span class="button-text">%text</span></a> ',
  401.         // sibling: '[data-cmd="clearFormatting"]',
  402.         sibling: '.js-attachmentUpload',
  403.         siblingPos: 'before',
  404.         observe: '[data-xf-click="quick-edit"]',
  405.         observeCache: 1
  406.       },
  407.       palettes: {
  408.         default: ['transparent', '#505050', 'rgba(20,20,20,0.06)', '#141414']
  409.       },
  410.       check: 'XF',
  411.       // callback: function() {
  412.       //    $.FroalaEditor.RegisterCommand('PUP', {
  413.       //      title: 'PUP',
  414.       //        type: 'popup',
  415.       //      focus: false,
  416.       //      undo: false,
  417.       //      refreshAfterCallback: true,
  418.       //      callback: function (cmd) {
  419.       //            let el = this.$box[0].querySelector('[data-cmd="' + cmd + '"]');
  420.       //            el.classList.remove('fr-selected');
  421.       //            let id = el.getAttribute(PUP.ns.dataPluginId);
  422.       //            PUP.openPopup(id);
  423.       //      }
  424.       //    });
  425.       //    $(function() {
  426.       //        $('.js-editor')
  427.       //            .froalaEditor({
  428.       //                tooltips: true,
  429.       //              toolbarButtons: ['PUP'],
  430.       //            })
  431.       //   });
  432.       // },
  433.       // Use id to pass the target editor, if not... XF editor will always return the first editor (DOM) for .js-editor selector
  434.       getEditorFn: function(id) {
  435.         var sel = '.js-editor';
  436.         if(typeof id == 'string') {
  437.           sel = this.getEditorSel(id);
  438.         }
  439.         return XF.getEditorInContainer($(sel));
  440.       },
  441.       getEditorSel: function(id) {
  442.         return '[' + PUP.ns.dataPluginTarget + '="'+ id + '"]';
  443.       },
  444.       getEditor: function(id) {
  445.         if(typeof id == 'string') {
  446.           return document.querySelector(this.getEditorSel(id));
  447.         }
  448.         return document.querySelectorAll('.js-editor');
  449.       },
  450.       getBbCode: function(edFnCode) {
  451.         return edFnCode.getTextArea()[0].value;
  452.       },
  453.       editorValue: function(str, id) {
  454.         var nl = '<p><br></p>';
  455.         var edFn = this.getEditorFn(id);
  456.         var type = edFn.ed.bbCode.isBbCodeView() ? ['bbCode', 'getBbCode', 'insertBbCode'] : ['html', 'get', 'insert'];
  457.         var edFnCode = edFn.ed[type[0]];
  458.         if(typeof str == 'string') {
  459.           var jump = this.editorValue(false, id) !== '';
  460.           if(type[0] == 'html') {
  461.             var insert = '<p>' + str + '</p>';
  462.             edFnCode[type[2]](jump ? (nl + insert) : insert);
  463.           } else {
  464.             var XHR = XF.ajax('POST', XF.canonicalizeUrl('index.php?editor/to-bb-code'), {
  465.               html: str
  466.             });
  467.             XHR.done(function(data) {
  468.               edFnCode[type[2]](jump ? ("\n" + data.bbCode) : data.bbCode);
  469.             });
  470.           }
  471.           return;
  472.         }
  473.         if(typeof edFnCode[type[1]] == typeof undefined) {
  474.           var value = this.getBbCode(edFnCode);
  475.         } else {
  476.           var value = edFnCode[type[1]]();
  477.         }
  478.         if(this.useCustomEditor() && value == nl) {
  479.           return '';
  480.         }
  481.         return value;
  482.       },
  483.       useCustomEditor: function() {
  484.         return typeof XF.getEditorInContainer($('.js-editor')) !== typeof undefined;
  485.       }
  486.     }
  487.   },
  488.   generateGuid: function() {
  489.     var d = new Date().getTime();
  490.     if (typeof performance !== 'undefined' && typeof performance.now === 'function'){
  491.         d += performance.now();
  492.     }
  493.     return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
  494.         var r = (d + Math.random() * 16) % 16 | 0;
  495.         d = Math.floor(d / 16);
  496.         return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
  497.     });
  498.   },
  499.   getNewValue: function(el, msg) {
  500.     var prop = typeof el.getAttribute('contenteditable') !== 'string' ? 'value' : 'innerHTML';
  501.     var newline = prop == 'value' ? '\n' : '<br>';
  502.     var value =  el[prop];
  503.     var fixed = msg;
  504.     var escape = false;
  505.     if(escape) {
  506.       fixed = String(msg).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
  507.     }
  508.     if(value.length == 0) {
  509.       return fixed;
  510.     }
  511.     var ret = '';
  512.     var match = value.match(/\n+$/g);
  513.     var newlines = match ? match[0].split("\n").length : 0;
  514.     if(newlines <= 2) {
  515.       var repeats = newlines == 0 ? 2 : 1;
  516.       ret += newline.repeat(repeats);
  517.     }
  518.     return ret + fixed;
  519.   },
  520.   insertTrigger: function() {
  521.     var vendor = this.vendors[this.settings.vendor];
  522.     var sibling = !this.settings.sibling ? 0 : document.querySelectorAll(this.settings.sibling + ':not([' + this.ns.dataPlugin + '])')[0];
  523.     var areas;
  524.     if(this.settings.mode == 'auto') {
  525.       areas = this.vendors[vendor.hasOwnProperty('getEditor') ? this.settings.vendor : 'default'].getEditor();
  526.     } else {
  527.       var targets = document.querySelectorAll('[' + this.ns.dataPluginTrigger + '][data-target]:not([' + this.ns.dataPluginId + '])');
  528.       var targetsSel = [];
  529.       for(var i=0; i<targets.length; i++) {
  530.         targetsSel.push(targets[i].dataset.target);
  531.       }
  532.       if(targetsSel.length > 0) {
  533.         areas = document.querySelectorAll(targetsSel.join(','));
  534.       }
  535.     }
  536.     if(!areas) {
  537.       return;
  538.     }
  539.     if(!document.getElementById(this.ns.pluginStyle) && this.settings.css) {
  540.       var style = document.createElement('style');
  541.       var rules = this.settings.css;
  542.       rules = this.appyTemplate(rules);
  543.       style.type = 'text/css';
  544.       style.innerHTML = rules.replace(/%p/g, '.' + this.ns.plugin);
  545.       style.setAttribute('id', this.ns.pluginStyle);
  546.       document.body.appendChild(style);
  547.     }
  548.     if(!(areas instanceof NodeList)) {
  549.       areas = [areas];
  550.     }
  551.  
  552.     var count = 0;
  553.     for (var i=0; i<areas.length; i++) {
  554.       if(areas[i].getAttribute(this.ns.dataPluginTarget)) {
  555.         continue;
  556.       };
  557.       var target = sibling ? sibling : areas[i];
  558.       target.setAttribute(this.ns.dataPlugin, 'sibling');
  559.       target.insertAdjacentHTML({before: 'beforebegin', after: 'afterend'}[this.settings.siblingPos],
  560.       this.appyTemplate(this.settings.html));
  561.       var trigger = target.parentElement.querySelector('[' + this.ns.dataPluginTrigger + ']');
  562.       this.setBoundId(trigger, areas[i]);
  563.       count++;
  564.     }
  565.     this.triggerCounter = count;
  566.     if(typeof vendor.callback == 'function') {
  567.       vendor.callback.call();
  568.     }
  569.   },
  570.   appyTemplate: function(template) {
  571.     if(!this.cacheTable) {
  572.       var table = [
  573.         {'%iconSvg': this.iconSvg},
  574.         {'%text': this.settings.langString}
  575.       ];
  576.       if(this.palette) {
  577.         var re = /%(\d+)/g;
  578.         var match = re.exec(template);
  579.         var arr = [];
  580.         while(match !== null) {
  581.             if(arr.indexOf(match[1]) == -1) {
  582.               arr.push(match[1]);
  583.             }
  584.             match = re.exec(template);
  585.         }
  586.         if(arr) {
  587.           arr.sort(function(a,b) {
  588.             return b-a;
  589.           });
  590.           var vendor = this.vendors[this.settings.vendor];
  591.           for(var i=0; i<arr.length; i++) {
  592.             var index = arr[i] - 1;
  593.             var value = this.palette[index] || '';
  594.             if(!value && this.settings.vendor !== 'default' && this.settings.palette !== 'default') {
  595.               value = this.palette[index - 2];
  596.             }
  597.             var o = {};
  598.             o['%' + arr[i]] = value;
  599.             table.push(o);
  600.           }
  601.         }
  602.       }
  603.       var bClass = this.settings.buttonClass || (this.ns.plugin + '-button');
  604.       var named = [
  605.         {'%cClass': this.settings.containerClass || (this.ns.plugin + '-container')},
  606.         {'%bClass': bClass},
  607.         {'%iClass': bClass + '-icon'},
  608.         {'%tClass': bClass + '-text'},
  609.         {'%x': this.ns.dataPluginTrigger},
  610.         {'%p': this.ns.plugin},
  611.       ];
  612.       for(var i=0; i<named.length; i++) {
  613.         table.push(named[i])
  614.       }
  615.       this.cacheTable = table;
  616.     }
  617.     return this.strtr(template, this.cacheTable);
  618.   },
  619.   strtr: function(str, replaces) {
  620.     var str = str.toString();
  621.     if(!str || typeof replaces == typeof undefined) {
  622.       return str;
  623.     }
  624.     for (var i=0; i<replaces.length; i++) {
  625.       var obj = replaces[i];
  626.       for(var key in obj) {
  627.         if (typeof obj[key] !== typeof undefined) {
  628.           re = new RegExp(key, 'g');
  629.           str = str.replace(re, obj[key]);
  630.         }
  631.       }
  632.     }
  633.     return str;
  634.   },
  635.   setBoundId: function(trigger, target) {
  636.     var id = this.generateGuid();
  637.     trigger.setAttribute(this.ns.dataPluginId, id);
  638.     // target.setAttribute(this.ns.dataPluginId, id);
  639.     target.setAttribute(this.ns.dataPluginTarget, id);
  640.   },
  641.   openPopup: function(id) {
  642.     if(typeof id !== "string") {
  643.       return
  644.     };
  645.     var self = this;
  646.     if(typeof this.popups == typeof undefined) {
  647.       this.popups = {};
  648.     }
  649.     if(typeof this.popups[id] !== typeof undefined) {
  650.       this.popups[id].window.focus();
  651.       return;
  652.     } else {
  653.       this.popups[id] = {};
  654.     }
  655.     var client = {
  656.       l: window.screenLeft != undefined ? window.screenLeft : screen.left,
  657.       t: window.screenTop != undefined ? window.screenTop : screen.top,
  658.       w: window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width,
  659.       h: window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height
  660.     };
  661.     var size = {
  662.       w: 720,
  663.       h: 690
  664.     };
  665.     var tolerance = {
  666.       w: 0.5,
  667.       h: 0.85
  668.     };
  669.     for(var key in size) {
  670.       if(size[key]/client[key] > tolerance[key]) {
  671.         size[key] = client[key] * tolerance[key];
  672.       }
  673.     }
  674.     var pos = {
  675.       l: Math.trunc(((client.w / 2) - (size.w / 2)) + client.l),
  676.       t: Math.trunc(((client.h / 2) - (size.h / 2)) + client.t)
  677.     };
  678.     this.popups[id].window = window.open(this.settings.url, id, 'width=' + size.w + ',height=' + size.h + ',top=' + pos.t + ',left=' + pos.l);
  679.     this.popups[id].timer = window.setInterval(function() {
  680.       if (!self.popups[id].window || self.popups[id].window.closed !== false) {
  681.           window.clearInterval(self.popups[id].timer);
  682.           self.popups[id] = undefined;
  683.       }
  684.     }, 200);
  685.   },
  686.   postSettings: function(id) {
  687.     this.popups[id].window.postMessage({id: id, settings: this.settings}, this.settings.url);
  688.   },
  689.   liveBind: function(qs, et, c) {
  690.     document.addEventListener(et, function(e) {
  691.       var caller = document.querySelectorAll(qs);
  692.       if(!caller) {
  693.         return;
  694.       }
  695.       var el = e.target;
  696.       var index = -1;
  697.       while (el && ((index = Array.prototype.indexOf.call(caller, el)) === -1)) {
  698.         el = el.parentElement;
  699.       }
  700.       if (index > -1) {
  701.         e.preventDefault();
  702.         c.call(e, el);
  703.       }
  704.     }, true);
  705.   },
  706.   prepare: function() {
  707.     var self = this;
  708.     this.ns.dataPlugin = 'data-' + this.ns.plugin;
  709.     this.ns.dataPluginId = this.ns.dataPlugin + '-id';
  710.     this.ns.dataPluginTrigger = this.ns.dataPlugin + '-trigger';
  711.     this.ns.dataPluginTarget = this.ns.dataPlugin + '-target';
  712.     this.ns.pluginStyle = this.ns.plugin + '-style';
  713.     this.ns.selDataPluginTrigger = '[' + this.ns.dataPluginTrigger + ']';
  714.     var srcEl = document.currentScript || document.getElementById(this.ns.plugin + '-src');
  715.     if(!srcEl) {
  716.       srcEl = {dataset: {}};
  717.     } else if(srcEl.dataset['buttonTemplate']) {
  718.       srcEl.dataset['html'] = srcEl.dataset['buttonTemplate'];
  719.     }
  720.     var nocss = 0;
  721.     this.settings = {};
  722.     settings = this.settings;
  723.     for(var key in this.defaultSettings) {
  724.       var value = (srcEl && srcEl.dataset[key]) ? srcEl.dataset[key] : this.defaultSettings[key];
  725.       if(value === '1' || value === '0') {
  726.         value = (value == 'true');
  727.       }
  728.       if(typeof value == 'string' && this.classProps.indexOf(key.replace(/Class$/, '')) > -1) {
  729.         nocss = 1;
  730.       }
  731.       settings[key] = value;
  732.     }
  733.     if(settings.vendor == 'auto') {
  734.       settings.vendor = 'default';
  735.       settings.fitEditor = 0;
  736.       for(var key in this.vendors) {
  737.         if(key == 'default') continue;
  738.         if(typeof window[this.vendors[key].check] !== typeof undefined) {
  739.           settings.vendor = key;
  740.           break;
  741.         }
  742.       }
  743.     }
  744.     if(settings.vendor == 'default') {
  745.       this.vendors.default.settings = {};
  746.       var skip = ['lang','url','vendor','target'];
  747.       for(var key in this.defaultSettings) {
  748.         if(skip.indexOf(key) == -1) {
  749.           this.vendors.default.settings[key] = this.defaultSettings[key];
  750.         }
  751.       }
  752.     }
  753.     var vendor = this.vendors[settings.vendor];
  754.     if(vendor.settings) {
  755.       for(var key in vendor.settings) {
  756.         if(!srcEl || !srcEl.dataset.hasOwnProperty(key)) {
  757.           settings[key] = vendor.settings[key];
  758.         }
  759.       }
  760.     }
  761.     if(settings.vendor !== 'default') {
  762.       if(!vendor.settings.hasOwnProperty('fitEditor') && !srcEl.dataset.hasOwnProperty('fitEditor')) {
  763.         settings.fitEditor = 1;
  764.       }
  765.       if(settings.fitEditor) {
  766.         nocss = !vendor.settings.css;
  767.       } else {
  768.         var skip = ['autoInsert', 'observe', 'observeCache'];
  769.         for(var key in vendor.settings) {
  770.           if(skip.indexOf(key) == -1 && !srcEl.dataset.hasOwnProperty(key)) {
  771.             settings[key] = this.defaultSettings[key];
  772.           }
  773.         }
  774.       }
  775.     }
  776.     if(nocss) {
  777.       settings.css = '';
  778.     } else {
  779.       settings.css = settings.css.replace('%defaultCSS', this.defaultSettings.css);
  780.       if(vendor.settings.extracss && settings.css) {
  781.         settings.css += vendor.settings.extracss;
  782.       }
  783.       var palette = settings.palette.split(',');
  784.       if(palette.length > 1) {
  785.         this.palette = palette;
  786.       } else if(!this.palettes.hasOwnProperty(palette)) {
  787.         settings.palette = 'default';
  788.       }
  789.       if(!this.palette) {
  790.         this.palette = (settings.fitEditor && vendor.palettes && vendor.palettes[settings.palette] ? vendor : this).palettes[settings.palette];
  791.       }
  792.     }
  793.     var props = this.classProps;
  794.     for(var i=0; i<props.length; i++) {
  795.       var prop = props[i] + 'Class';
  796.       if(typeof settings[prop] !== 'string') {
  797.         settings[prop] = this.ns.plugin + '-' + props[i];
  798.         if(settings.fitEditor) {
  799.           settings[prop] += '--' + settings.vendor;
  800.         }
  801.       }
  802.     }
  803.     var clientLang = (settings.lang == 'auto' ? (navigator.language || navigator.userLanguage) : settings.lang).replace('-', '_');
  804.     settings.langString = 'Upload images';
  805.     var langKey = clientLang in this.l10n ? clientLang : (clientLang.substring(0,2) in this.l10n ? clientLang.substring(0,2) : null);
  806.     if(langKey) {
  807.       settings.langString = this.l10n[langKey];
  808.     }
  809.     var parser = document.createElement('a');
  810.     parser.href = settings.url;
  811.     this.originUrlPattern = '^' + (parser.protocol + '//' + parser.hostname).replace(/\./g, '\\.').replace(/\//g, '\\/') + '$';
  812.     var namedTargets = document.querySelectorAll(this.ns.selDataPluginTrigger + '[data-target]');
  813.     if(namedTargets.length > 0) {
  814.       for (var i=0; i<namedTargets.length; i++) {
  815.         var target = document.querySelector(namedTargets[i].dataset.target);
  816.         this.setBoundId(namedTargets[i], target);
  817.       }
  818.     }
  819.     if(settings.observe) {
  820.       var observe = settings.observe;
  821.       if(settings.observeCache) {
  822.         observe += ':not([' + this.ns.dataPlugin + '])';
  823.       }
  824.       this.liveBind(observe, 'click', function(el) {
  825.         el.setAttribute(self.ns.dataPlugin, 1);
  826.         self.observe();
  827.       }.bind(this));
  828.     }
  829.     if(settings.sibling && !settings.onDemand) {
  830.       this.waitForSibling();
  831.     } else {
  832.       if(settings.init == 'onload') {
  833.         if(document.readyState === 'loading') {
  834.           document.addEventListener('DOMContentLoaded', function(event) {
  835.             self.init();
  836.           }, false);
  837.         } else {
  838.           this.init();
  839.         }
  840.       } else {
  841.         this.observe();
  842.       }
  843.     }
  844.   },
  845.   observe: function() {
  846.     this.waitForSibling('observe');
  847.   },
  848.   waitForSibling: function(m) {
  849.     var fn = this.initialized ? 'insertTrigger' : 'init';
  850.     if(this.settings.sibling) {
  851.       var sibling =  document.querySelector(this.settings.sibling + ':not([' + this.ns.dataPlugin + '])');
  852.     } else if(m == 'observe') {
  853.       this[fn]();
  854.       if(this.triggerCounter) {
  855.         return;
  856.       }
  857.     }
  858.     if(!sibling) {
  859.       if(document.readyState === 'complete' && m !== 'observe') {
  860.         return;
  861.       }
  862.       setTimeout((m == 'observe' ? this.observe : this.waitForSibling).bind(this), 250);
  863.     } else {
  864.       this[fn]();
  865.     }
  866.   },
  867.   init: function() {
  868.     this.insertTrigger();
  869.     var self = this;
  870.     var vendor = this.vendors[this.settings.vendor];
  871.     this.liveBind(this.ns.selDataPluginTrigger, 'click', function(el) {
  872.       var id = el.getAttribute(self.ns.dataPluginId);
  873.       self.openPopup(id);
  874.     });
  875.     window.addEventListener('message', function(e) {
  876.       var regex = new RegExp(self.originUrlPattern, 'i');
  877.       if (!regex.test(e.origin) && (typeof e.data.id == typeof undefined || typeof e.data.message == typeof undefined) ) {
  878.         return;
  879.       };
  880.       var id = e.data.id;
  881.       if(!id || e.source !== self.popups[id].window) {
  882.         return;
  883.       }
  884.       if(e.data.requestAction && self.hasOwnProperty(e.data.requestAction)) {
  885.         self[e.data.requestAction](id);
  886.         return;
  887.       }
  888.       var area;
  889.       if(self.settings.vendor !== 'default') {
  890.         if(vendor.hasOwnProperty('useCustomEditor') && vendor.useCustomEditor()) {
  891.           vendor.editorValue(e.data.message, id);
  892.           return;
  893.         } else if(vendor.hasOwnProperty('getEditor')) {
  894.           area = vendor.getEditor();
  895.         }
  896.       }
  897.       if(!area) {
  898.           area = document.querySelector('[' + self.ns.dataPluginTarget + '="' + id + '"]');
  899.           if(!area) {
  900.             alert("Target not found"); // calma calma que no panda el cúnico
  901.             return;
  902.           }
  903.       }
  904.       var valueProp = area.getAttribute('contenteditable') === null ? 'value' : 'innerHTML';
  905.       area[valueProp] += self.getNewValue(area, e.data.message);
  906.       var events = ['blur', 'focus', 'input', 'change', 'paste'];
  907.       for(var i=0; i<events.length; i++) {
  908.         var event = new Event(events[i]);
  909.         area.dispatchEvent(event);
  910.       }
  911.     }, false);
  912.     this.initialized = 1;
  913.   }
  914. };
  915. var redactor2 = ["WoltLab", "XF1"];
  916. for(var i=0; i<redactor2.length; i++) {
  917.   PUP.vendors[redactor2[i]] = Object.assign(Object.assign({}, PUP.vendors.redactor2), PUP.vendors[redactor2[i]]);
  918. }
  919. PUP.prepare();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement