Вход Регистрация
Файл: js/xenforo/full/template_edit.js
Строк: 723
<?php
/**
 * @todo The order of methods in this class is somewhat random.
 */

//TODO: Capitalise all lowercase IDs required by Javascript (#templateEditor etc.)

/** @param {jQuery} $ jQuery Object */
!function($, windowdocument_undefined)
{
    
XenForo.TemplateEditor = {};

    
/**
     * Multi-tab template editor
     *
     * @param jQuery form#templateEditor
     */
    
XenForo.TemplateEditor = function($form) { this.__construct($form); };
    
XenForo.TemplateEditor.prototype =
    {
        
__construct: function($form)
        {
            
this.useAjaxSave true;

            
this.setupEditors($form);
        },

        
/**
         * Setup for multi-tab editor
         *
         * @param jQuery Template Editor
         */
        
setupEditors: function($form)
        {
            
this.initialized false;

            
/**
             * Forms and form fields
             */
            
this.$form             $form;
            
this.$styleId          = $('#styleId');
            
this.$templateId       = $('#templateId');

            
this.$titleOriginal    = $('#templateTitleOriginal');

            
/*if (!this.$titleOriginal.strval())
            {
                return;
            }*/

            
this.$templateTitle    = $('#templateTitle');
            
this.$templateTextarea = $('#templateTextarea');

            
this.$saveReloadButton = $('#saveReloadButton');
            
this.$saveExitButton   = $('#saveExitButton');

            
/**
             * Tab-related stuff
             */
            
this.$changeIndicator  this.createChangeIndicator();
            
this.$templateTab      = $('#templateTab');
            
this.$editorTabs       = $('#editorTabs');

            
this.$primaryOnly $form.find('.PrimaryTemplateOnly');

            
/**
             * Misc storage
             */
            
this.editors = {};
            
this.templateData = {
                
'': {
                    
style_id0,
                    
template_id0,
                    
template''
                
}
            };

            
/**
             *  css requires and template includes
             */
            
this.requireRegex = new RegExp('<xen:(require|include|edithint) [^>]*(css|template)="([^"]+)"[^>]*/?>''gi');

            if (
this.$titleOriginal.strval())
            {
                
this.loadTemplates(this.getIncludeTitles());
            }
            else
            {
                
this.initialize();
            }
        },

        
/**
         * Reads the main template to work out what CSS is required or templates included,
         * loads the required templates via AJAX,
         * then builds tabs and editors for the required templates
         */
        
loadTemplates: function(titles)
        {
            if (
titles.length)
            {
                
XenForo.ajax(
                    
this.getLoadUrl('json'),
                    {
                        
includeTitlestitles,
                        
style_idthis.$styleId.val(),
                        
_TemplateEditorAjax1
                    
},
                    $.
context(this'ajaxLoadSuccess'),
                    { 
type'GET' }
                );
            }
        },

        
/**
         * AJAX callback for the template loader
         *
         * @param data
         * @param textStatus
         */
        
ajaxLoadSuccess: function(ajaxDatatextStatus)
        {
            if (
XenForo.hasResponseError(ajaxData))
            {
                return 
false;
            }

            
this.templateData ajaxData.templates;

            if (!
this.initialized)
            {
                
this.initialize();
            }

            
this.handleTitleChange();

            
this.refreshEditors();
        },

        
initialize: function()
        {
            
this.initializePrimaryEditor();

            
this.updateSaveActions();

            var 
initUndo = function($textarea)
                {
                    if (!
$textarea.data('undoStack'))
                    {
                        
$textarea.data('undoStack', [[$textarea.val(), 00]]);
                    }
                },
                
pushUndo = function($textarearesetRedo)
                {
                    var 
textarea $textarea[0],
                        
stack $textarea.data('undoStack');

                    if (!
stack)
                    {
                        
stack = [];
                    }

                    
stack.push(
                        [
$textarea.val(), textarea.selectionStarttextarea.selectionEnd]
                    );

                    
$textarea.data('undoStack'stack);
                    if (
resetRedo)
                    {
                        
$textarea.data('redoStack', []);
                    }
                },
                
popUndo = function($textarea)
                {
                    var 
textarea $textarea[0],
                        
undoStack $textarea.data('undoStack'),
                        
undo,
                        
redoStack $textarea.data('redoStack');

                    if (!
redoStack)
                    {
                        
redoStack = [];
                    }
                    
redoStack.push(
                        [
$textarea.val(), textarea.selectionStarttextarea.selectionEnd]
                    );
                    
$textarea.data('redoStack'redoStack);

                    if (
undoStack && undoStack.length)
                    {
                        
undo undoStack.pop();
                        
$textarea.val(undo[0]);
                        
textarea.selectionStart undo[1];
                        
textarea.selectionEnd undo[2];
                        
$textarea.data('lastSelPosition'undo[2]);
                    }

                },
                
popRedo = function($textarea)
                {
                    var 
textarea $textarea[0],
                        
undoStack $textarea.data('undoStack'),
                        
redoStack $textarea.data('redoStack'),
                        
redo;

                    if (
redoStack && redoStack.length)
                    {
                        
pushUndo($textareafalse);

                        
redo redoStack.pop();
                        
$textarea.val(redo[0]);
                        
textarea.selectionStart redo[1];
                        
textarea.selectionEnd redo[2];
                        
$textarea.data('lastSelPosition'redo[2]);
                    }
                },
                
updateLastSelPosition = function($textarea)
                {
                    var 
lastSelPosition $textarea.data('lastSelPosition'),
                        
pushed false;

                    if (
typeof lastSelPosition != 'undefined' && !isNaN(lastSelPosition))
                    {
                        if (
$textarea[0].selectionEnd != lastSelPosition)
                        {
                            
pushUndo($textareatrue);
                            
pushed true;
                        }
                    }

                    
setTimeout(function() {
                        
$textarea.data('lastSelPosition'$textarea[0].selectionEnd);
                    }, 
0);

                    return 
pushed;
                };

            var 
self this;
            
this.$form.on('keypress''.textCtrl.code', function(e)
            {
                
updateLastSelPosition($(this));
            });
            
this.$form.on('keydown''.textCtrl.code', function(e)
            {
                var 
$this = $(this);
                
initUndo($this);

                if (
e.keyCode == 13)
                {
                    
pushUndo($thistrue);
                }

                if (
e.keyCode == 90 && (e.metaKey || e.ctrlKey)) // ctrl+z
                
{
                    
e.preventDefault();

                    if (
e.shiftKey)
                    {
                        
// redo
                        
popRedo($this);
                    }
                    else
                    {
                        
// undo
                        
popUndo($this);
                    }
                }
                else if (
e.keyCode == 89 && (e.metaKey || e.ctrlKey)) // ctrl+y
                
{
                    
// redo
                    
e.preventDefault();
                    
popRedo($this);
                }
                else if (
e.keyCode == && !e.metaKey && !e.ctrlKey && !e.altKey// tab, no modifiers
                
{
                    
e.preventDefault();

                    var 
start this.selectionStart,
                        
end this.selectionEnd,
                        
val $this.val(),
                        
before val.substring(0start),
                        
after val.substring(end);

                    var 
replace true;
                    if (
start != end)
                    {
                        var 
sel val.substring(startend);
                        if (
sel.indexOf("n") != -1)
                        {
                            
replace false;
                            var 
lenAdjust 0;

                            var 
lastLineBreak before.lastIndexOf("n");
                            if (
lastLineBreak == -1)
                            {
                                
// first line
                                
sel before sel;
                                
lenAdjust before.length;
                                
before '';
                            }
                            else
                            {
                                
sel before.substring(lastLineBreak) + sel;
                                
lenAdjust before.length lastLineBreak;
                                
before before.substring(0lastLineBreak);
                            }

                            if (
e.shiftKey)
                            {
                                var 
regex = /(n|^)(t|[ ]{1,8})/g;

                                if (
sel.match(regex))
                                {
                                    
start -= 1;
                                    
lenAdjust--;
                                }
                                
sel sel.replace(regex"$1");
                            }
                            else
                            {
                                
sel sel.replace(/(n|^)/g"$1t");
                                
start += 1;
                                
lenAdjust++;
                            }

                            
pushUndo($thistrue);
                            
$this.val(before sel after);
                            
this.selectionStart start;
                            
this.selectionEnd start sel.length lenAdjust;
                        }
                    }

                    if (
replace && !e.shiftKey)
                    {
                        
$this.val(before "t" after);
                        
this.selectionStart this.selectionEnd start 1;
                    }
                }
                else if (
e.keyCode == 13 && !e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey)
                {
                    var 
start this.selectionStart,
                        
end this.selectionEnd,
                        
val $this.val(),
                        
before val.substring(0start),
                        
after val.substring(end),
                        
lastLineBreak before.lastIndexOf("n");
                    var 
searchString = (lastLineBreak == -before before.substring(lastLineBreak 1)),
                        
match searchString.match(/^(s+)/);

                    if (
match)
                    {
                        
e.preventDefault();
                        
$this.val(before "n" match[1] + after);
                        
this.selectionStart this.selectionEnd start match[1].length 1;
                    }
                }
                else if (
e.keyCode == 83 && (e.ctrlKey || e.metaKey)) // ctrl/cmd+s
                
{
                    
e.preventDefault();
                    
self.$saveReloadButton.click();
                }
            });
            
this.$form.on('cut paste''.textCtrl.code', function() {
                if (!
updateLastSelPosition($(this)))
                {
                    
pushUndo($(this), true);
                }
            });
        },

        
/**
         * Like createEditor(), except turns the initial, primary editor into
         * a Javascript-activated editor
         */
        
initializePrimaryEditor: function()
        {
            var 
templateId this.$templateId.strval(),
                
templateTitle this.$titleOriginal.strval(),
                
$changeIndicator this.createChangeIndicator();

            
console.log('Initializing primary editor for template %s, id %s', (templateTitle templateTitle '(untitled)'), templateId);

            
this.editors[templateTitle] =
            {
                
templateIdthis.$templateId.val(),
                
$changeIndicator$changeIndicator,

                
$styleId: $(document.createElement('input'))
                    .
attr({
                        
type'hidden',
                        
name'styleidArray[' templateId ']'
                    
})
                    .
val(this.templateData[templateTitle].style_id),

                
$tabthis.$templateTab,

                
$titlethis.$templateTitle
                    
.attr({
                        
templateTitletemplateTitle,
                        
name'titleArray[' templateId ']'
                    
})
                    .
keyup($.context(this'eTitleChange'))
                    .
blur($.context(this'setBlurItem')),

                
$textareathis.$templateTextarea
                    
.attr({
                        
templateTitletemplateTitle,
                        
name'templateArray[' templateId ']'
                    
})
                    .
keyup($.context(this'eTemplateChange'))
                    .
blur($.context(this'setBlurItem'))
            };

            
this.editors[templateTitle].$tab.find('a')
                .
append('&nbsp;')
                .
attr('templateTitle'templateTitle)
                .
addClass(this.getInheritanceState(templateTitle))
                .
click($.context(this'switchEditor'))
                .
prepend(this.editors[templateTitle].$changeIndicator)
                .
prepend(this.editors[templateTitle].$styleId);

            
this.initialized true;
        },

        
/**
         * Registers the last item to be blurred
         *
         * @param e
         * @return
         */
        
setBlurItem: function(e)
        {
            
this.blurItem e.target;
        },

        
/**
         * Focuses the element most recently set as this.blurItem
         */
        
focusBlurItem: function()
        {
            if (
this.blurItem !== undefined)
            {
                
this.blurItem.focus();
            }
        },

        
/**
         * Creates tabs representing each required CSS / included template
         */
        
refreshEditors: function()
        {
            var 
templateTitle null$lastTab null;

            for (
templateTitle in this.templateData)
            {
                if (
typeof this.templateData[templateTitle] != 'function')
                {
                    if (
this.editors[templateTitle] === undefined)
                    {
                        
// create a new editor
                        
this.editors[templateTitle] = this.createEditor(templateTitle$lastTab);
                    }
                    else
                    {
                        
// update an existing editor
                        
this.updateEditor(templateTitle);
                    }

                    
$lastTab this.editors[templateTitle].$tab;
                }
            }

            
// check for editors that still exist that are not in the templateData
            
for (templateTitle in this.editors)
            {
                if (
typeof this.editors[templateTitle] != 'function')
                {
                    if (
this.templateData[templateTitle] === undefined)
                    {
                        
this.destroyEditor(templateTitle);
                    }
                }
            }
        },

        
/**
         * Creates a single tab and editor
         *
         * @param integer Index of current data within this.templateData
         *
         * @return object Editor
         */
        
createEditor: function(templateTitle$prevTab)
        {
            var 
data this.templateData[templateTitle],
                
$changeIndicator this.createChangeIndicator(),
                
$tab = $('<a />')
                    .
html(templateTitle '&nbsp;')
                    .
attr('href'data.link)
                    .
attr('templateTitle'templateTitle)
                    .
addClass(this.getInheritanceState(templateTitle))
                    .
prepend($changeIndicator)
                    .
click($.context(this'switchEditor')),
                
editor = {};

            
editor =
            {
                
templateIddata.template_id,

                
$styleId: $(document.createElement('input'))
                    .
attr({
                        
type'hidden',
                        
name'styleidArray[' data.template_id ']'
                    
})
                    .
val(data.style_id),

                
$changeIndicator$changeIndicator,

                
$tab: $('<li />').append($tab),

                
$textareathis.$templateTextarea.clone(true)
                    .
xfHide()
                    .
attr({
                        
templateTitletemplateTitle,
                        
name'templateArray[' data.template_id ']'
                    
})
                    .
removeAttr('id')
                    .
val(data.template)
                    .
keyup($.context(this'eTemplateChange')),

                
$title: $(document.createElement('input'))
                    .
attr({
                        
type'hidden',
                        
name'titleArray[' data.template_id ']'
                    
})
                    .
val(data.title)
            };

            if (
$prevTab)
            {
                
$prevTab.after(editor.$tab);
            }
            else
            {
                
this.$editorTabs.append(editor.$tab);
            }

            
this.getTextareaWrapper()
                .
append(editor.$textarea)
                .
append(editor.$title)
                .
append(editor.$styleId);

            return 
editor;
        },

        
/**
         * Updates a single editor
         *
         * @param string templateTitle
         */
        
updateEditor: function(templateTitle)
        {
            var 
editor this.editors[templateTitle],
                
data this.templateData[templateTitle];

            if (
editor.templateId != data.template_id)
            {
                if (
this.isPrimaryTemplate(templateTitle))
                {
                    
console.log('Primary template updated');

                    
this.$templateId.val(data.template_id);

                    var 
$deleteButton = $('#TemplateDeleteButton');
                    if (
data.deleteLink)
                    {
                        
$deleteButton.data('href'data.deleteLink).show();
                    }
                    else
                    {
                        
$deleteButton.hide();
                    }
                }

                
editor.$tab.find('a')
                    .
removeClass('master custom inherited')
                    .
addClass(this.getInheritanceState(templateTitle));

                
editor.$textarea.attr('name''templateArray[' data.template_id ']');

                
editor.$title.attr('name''titleArray[' data.template_id ']');

                
editor.$styleId.attr('name''styleidArray[' data.template_id ']');
                
editor.$styleId.val(data.style_id);

                
editor.templateId data.template_id;
            }

            
this.handleTemplateChange(templateTitle);
        },

        
/**
         * Destroys an editor, its tab and its original value
         */
        
destroyEditor: function(templateTitle)
        {
            
this.editors[templateTitle].$tab.remove();

            
this.editors[templateTitle].$textarea.remove();

            
delete this.editors[templateTitle];
        },

        
/**
         * Alters the behaviours of the default save/reload button so that saves are done via AJAX
         */
        
updateSaveActions: function()
        {
            if (
this.useAjaxSave && this.getSaveUrl('json'))
            {
                
this.$saveReloadButton
                    
.val(this.$saveReloadButton.data('ajaxvalue'))
                    .
click($.context(this'saveAjax'));

                
this.$saveExitButton
                    
.click($.context(this'saveExit'));

                
this.$form.attr('action'this.getSaveUrl());
            }
        },

        
/**
         * Save all templates via AJAX request
         *
         * @param Event e
         *
         * @return boolean True
         */
        
saveAjax: function(e)
        {
            var 
postParamsiincludeTitlesdisableModifications;

            if (
e)
            {
                
e.preventDefault();
            }

            
disableModifications this.$form.find('input[name="disable_modifications"]').is(':checked');

            
this.toggleUnchangeFieldNames(disableModifications);

            
postParams this.$form.serializeArray();

            
this.toggleUnchangeFieldNames(true);

            
includeTitles this.getIncludeTitles();
            for (
0includeTitles.lengthi++)
            {
                
XenForo.ajaxDataPush(postParams'includeTitles[]'includeTitles[i]);
            }

            
XenForo.ajaxDataPush(postParams'_TemplateEditorAjax'1);

            
XenForo.ajax(
                
this.getSaveUrl('json'),
                
postParams,
                $.
context(this'ajaxSaveSuccess')
            );

            return 
true;
        },

        
/**
         * Intercept saving all templates via normal POST
         *
         * @param Event e
         *
         * @return boolean True
         */
        
saveExit: function(e)
        {
            
this.toggleUnchangeFieldNames(false);

            return 
true;
        },

        
/**
         * Removes or restores the 'name' attribute for any editors whose content is unmodified
         * in order to prevent their values being sent through by the jQuery .serialize() function.
         *
         * @param boolean If true, restore removed name, otherwise remove name if contents are unchanged.
         */
        
toggleUnchangeFieldNames: function(restore)
        {
            var 
$textareatitleChanged;

            for (
templateTitle in this.editors)
            {
                if (
typeof this.editors[templateTitle] != 'function')
                {
                    
titleChanged false;

                    if (
this.isPrimaryTemplate(templateTitle) && this.$templateTitle.strval() != this.$titleOriginal.strval())
                    {
                        
titleChanged true;
                    }

                    if (!
this.isChanged(templateTitle) && !titleChanged && !$('input[name="disable_modifications"]').is(':checked'))
                    {
                        
$textarea this.editors[templateTitle].$textarea;

                        if (
restore)
                        {
                            
$textarea.attr('name'$textarea.attr('oName'));
                            
$textarea.removeAttr('oName');
                        }
                        else
                        {
                            
$textarea.attr('oName'$textarea.attr('name'));
                            
$textarea.removeAttr('name');
                        }
                    }
                }
            }
        },

        
/**
         * AJAX callback for the template saver
         */
        
ajaxSaveSuccess: function(ajaxDatatextStatus)
        {
            if (
XenForo.hasResponseError(ajaxData))
            {
                return 
false;
            }

            if (
ajaxData.saveMessage)
            {
                
XenForo.alert(ajaxData.saveMessage''1000);
            }

            
this.focusBlurItem();

            
// handle template renaming
            
var oldTitle this.$titleOriginal.strval(),
                
newTitle this.$templateTitle.strval();

            
/**
             * Check to see if the stored original template title is different from that in
             * the user-editable textbox. If it's different but the new title does not exist
             * in the returned AJAX data, we are looking at a page refresh. However, if it's
             * different and it DOES exist in the AJAX data, we are likely looking at a post-save
             * load, and should update the main editor object accordingly.
             */
            
if (oldTitle != newTitle && ajaxData.templates[newTitle] !== undefined)
            {
                
// update properties of main template editor object
                
this.editors[oldTitle].$tab.find('a').attr('templateTitle'newTitle);
                
this.editors[oldTitle].$title.attr('templateTitle'newTitle);
                
this.editors[oldTitle].$textarea.attr('templateTitle'newTitle);

                
// update 'hard-copy' of title value
                
this.$titleOriginal.val(newTitle);

                
// re-key main template editor object
                
this.editors[newTitle] = this.editors[oldTitle];
                
delete this.editors[oldTitle];
            }

            
this.ajaxLoadSuccess(ajaxDatatextStatus);
        },

        
/**
         * Fetches the inhertance state of a specified template
         *
         * @param string Template Title
         *
         * @return string master|custom|inherited
         */
        
getInheritanceState: function(templateTitle)
        {
            if (
this.templateData[templateTitle].style_id === undefined)
            {
                
// If undefined, we either have no data, or this is an admin template.
                
return 'master';
            }

            switch (
parseInt(this.templateData[templateTitle].style_id))
            {
                case 
0: return 'master';

                case 
parseInt(this.$styleId.val()): return 'custom';

                default: return 
'inherited';
            }
        },


        
/**
         * Read the primary template for t:require and t:include tags
         * and return an array of all their names
         *
         * @return array
         */
        
getIncludeTitles: function()
        {
            var 
titles = new Array(),
                
match,
                
i;

            if (
this.$titleOriginal.strval() != '')
            {
                
titles.push(this.$titleOriginal.strval());
            }

            if (
this.$templateTitle.strval() != '')
            {
                
titles.push(this.$templateTitle.strval());
            }

            if (
this.$templateTextarea.val().indexOf('{xen:pagenav') != -1)
            {
                
titles this.titlePush('page_nav'titles);
            }

            if (
match this.$templateTextarea.val().match(this.requireRegex))
            {
                for (
0match.lengthi++)
                {
                    
titles this.titlePush(match[i].replace(this.requireRegex'$3'), titles);
                }
            }

            return 
titles;
        },

        
/**
         * Pushes titleString and titleString.css onto titleArray
         *
         * @param string title
         * @param array titles
         *
         * @return array
         */
        
titlePush: function(titleStringtitleArray)
        {
            
titleArray.push(titleString);

            if (!
titleString.match(/.css$/))
            {
                
titleArray.push(titleString '.css');
            }

            return 
titleArray;
        },

        
/**
         * Returns (and creates if necessary) the wrapper for the textarea
         *
         * @return jQuery Textarea wrapper
         */
        
getTextareaWrapper: function()
        {
            if (
this._$textareaWrapper === undefined)
            {
                
/*
                 * @todo:
                 * need to get rid of the margin on the textarea and add it to the wrapper,
                 * get the width of the textarea and apply it to the wrapper,
                 * move the inline styling to a stylesheet,
                 * investigate scrollIntoView vs setting scrollTo in order to make the other editors appear from outside of the overflowed area
                 */

                
this.$templateTextarea.wrap('<div id="textareaWrapper" style="position:relative"></div>');

                
this._$textareaWrapper = $('#textareaWrapper')
                    .
width(this.$templateTextarea.width());
            }
            else
            {
            }

            return 
this._$textareaWrapper;
        },

        
/**
         * Returns an indicator to be inserted into tabs to show that a template contains unsaved changes
         *
         * @return jQuery
         */
        
createChangeIndicator: function()
        {
            return $(
document.createElement('span'))
                .
html('&bull;')
                .
css('visibility''hidden')
                .
addClass('changeIndicator');
        },

        
/**
         * Alters various properties of tabs (etc) to show that the contents of an editor is or is not changed from its initial (saved) value
         *
         * @param object $element
         * @param boolean changed
         *
         * @return boolean true
         */
        
setChanged: function($elementchanged)
        {
            if (
$element.attr('changed') != changed)
            {
                
$element.attr('changed'changed);
                
$element.css('visibility', (changed 'visible' 'hidden'));
                
$element.parent().css('color', (changed 'darkred' 'inherit'));
            }
            return 
changed;
        },

        
/**
         * Handles a click on a tab, switching the active editor
         * @param e
         * @return
         */
        
switchEditor: function(e)
        {
            var 
$target = $(e.target).closest('a'),
                
editor;

            
// switch the active tab
            
$target.closest('li')
                .
addClass('active')
                .
siblings().removeClass('active');

            
// switch the active editor
            
$('textarea'this.getTextareaWrapper())
                .
xfHide();

            
editor this.editors[$target.attr('templateTitle')];

            
editor.$textarea
                
.xfShow()
                .
focus();

            if (
this.$templateTextarea.is(':visible'))
            {
                
this.$primaryOnly.show();
            }
            else
            {
                
this.$primaryOnly.hide();
            }

            return 
false;
        },

        
/**
         * Key-up handler for title textbox
         *
         * @param event e
         */
        
eTitleChange: function(e)
        {
            
window.clearTimeout(this.titleChangeTimeout);

            
this.titleChangeTimeout window.setTimeout($.context(function() { this.handleTitleChange(); }, this), 500);
        },

        
/**
         * Updates the name of the first tab to reflect what the title input box says
         */
        
handleTitleChange: function()
        {
            var 
title this.$templateTitle.strval();

            $(
'.tabText'this.$templateTab)
                .
html((title || this.$form.data('untitled').italics()));
        },

        
/**
         * Key-up handler for editor textareas
         *
         * @param event e
         */
        
eTemplateChange: function(e)
        {
            
window.clearTimeout(this.templateChangeTimeout);

            var 
templateTitleClosure = $(e.target).attr('templateTitle');

            
this.templateChangeTimeout window.setTimeout($.context(function() { this.handleTemplateChange(templateTitleClosure); }, this), 500);
        },

        
/**
         * Returns whether or not the template specified is changed from its state at load
         *
         * @param string Template title
         *
         * @return boolean
         */
        
isChanged: function(templateTitle)
        {
            var 
editorValue this.editors[templateTitle].$textarea.strval().replace(/r/g''),
                
defaultValue this.templateData[templateTitle].template.replace(/r/g'');

            return (
editorValue != defaultValue);
        },

        
/**
         * Checks that the specified template is the primary template being edited
         *
         * @param string Template title
         *
         * @return boolean
         */
        
isPrimaryTemplate: function(templateTitle)
        {
            return (
templateTitle == this.$titleOriginal.strval());
        },

        
/**
         * Checks to see if an extra editor's value has changed from its default value
         * and updates the change indicator if it has
         *
         * @param string templateTitle
         *
         * @return boolean
         */
        
handleTemplateChange: function(templateTitle)
        {
            var 
changed this.isChanged(templateTitle);

            
this.setChanged(this.editors[templateTitle].$changeIndicatorchanged);

            return 
changed;
        },

        
/**
         * Gets the URL to load via AJAX for required templates
         *
         * @param string Request type
         *
         * @return string URL
         */
        
getLoadUrl: function(reqType)
        {
            return 
this.$form.data('loadurl') + (reqType ? ('.' reqType) : '');
        },

        
/**
         * Gets the URL to save via AJAX for altered templates
         *
         * @param string Request type
         *
         * @return string
         */
        
getSaveUrl: function(reqType)
        {
            return 
this.$form.data('saveurl') + (reqType ? ('.' reqType) : '');
        }
    };

    
// *********************************************************************

    
XenForo.register('form#templateEditor''XenForo.TemplateEditor');

}
(
jQuerythisdocument);
?>
Онлайн: 1
Реклама