closedquestion-8.x-3.x-dev/assets/js/libraries/jquery/jquery.maEditor.js

assets/js/libraries/jquery/jquery.maEditor.js
/**
 * maEditor
 * based on boilerplate version 1.3
 * @param {object} $ A jQuery object
 **/
(function ($) {
  "use strict"; //ECMA5 strict modus

  $.maEditor = function (element, settings) {
    /* define vars
     */

    /* this object will be exposed to other objects */
    var publicObj = this;

    //the version number of the plugin
    publicObj.version = "1.0";

    /* this object holds functions used by the plugin boilerplate */
    var _helper = {
      /**
       * Call hooks, additinal parameters will be passed on to registered plugins
       * @param {string} name
       */
      doHook: function (name) {
        var i;
        var pluginFunctionArgs = [];

        /* remove first two arguments */
        for (i = 1; i < arguments.length; i++) {
          pluginFunctionArgs.push(arguments[i]);
        }

        /* call plugin functions */
        if (_globals.plugins !== undefined) {
          /* call plugins */
          $.each(_globals.plugins, function (maEditor, extPlugin) {
            if (
              extPlugin.__hooks !== undefined &&
              extPlugin.__hooks[name] !== undefined
              ) {
              extPlugin.__hooks[name].apply(publicObj, pluginFunctionArgs);
            }
          });
        }

        /* trigger event on main element */
        _globals.$element.trigger(name, pluginFunctionArgs);
      },
      /**
       * Initializes the plugin
       */
      doInit: function () {
        _helper.doHook(
          "maEditor.beforeInit",
          publicObj,
          element,
          settings
          );
        publicObj.init();
        _helper.doHook("maEditor.init", publicObj);
      },
      /**
       * Loads an external script
       * @param {string} libName
       * @param {string} errorMessage
       */
      loadScript: function (libName, errorMessage) {
        /* remember libname */
        _cdnFilesToBeLoaded.push(libName);

        /* load script */
        $.ajax({
          type: "GET",
          url: _globals.dependencies[libName].cdnUrl,
          success: function () {
            /* forget libname */
            _cdnFilesToBeLoaded.splice(_cdnFilesToBeLoaded.indexOf(libName), 1); //remove element from _cdnFilesToBeLoaded array

            /* call init function when all scripts are loaded */
            if (_cdnFilesToBeLoaded.length === 0) {
              _helper.doInit();
            }
          },
          fail: function () {
            console.error(errorMessage);
          },
          dataType: "script",
          cache: "cache"
        });
      },
      /**
       * Checks dependencies based on the _globals.dependencies object
       * @returns {boolean}
       */
      checkDependencies: function () {
        var dependenciesPresent = true;
        for (var libName in _globals.dependencies) {
          var errorMessage =
            "jquery.maEditor: Library " +
            libName +
            " not found! This may give unexpected results or errors.";
          var doesExist = $.isFunction(_globals.dependencies[libName])
            ? _globals.dependencies[libName]
            : _globals.dependencies[libName].doesExist;
          if (doesExist.call() === false) {
            if (
              $.isFunction(_globals.dependencies[libName]) === false &&
              _globals.dependencies[libName].cdnUrl !== undefined
              ) {
              /* cdn url provided: Load script from external source */
              _helper.loadScript(libName, errorMessage);
            }
            else {
              console.error(errorMessage);
              dependenciesPresent = false;
            }
          }
        }
        return dependenciesPresent;
      }
    };
    /* keeps track of external libs loaded via their CDN */
    var _cdnFilesToBeLoaded = [];

    /* this object holds all global variables */
    var _globals = {};

    /* handle settings */
    var defaultSettings = {
      "input": $(''),
      "question_options": [],
      "allowDuplicates": false,
      "horizontalAlignment": false,
      "onlyOrder": -1
    };

    _globals.settings = {};

    if ($.isPlainObject(settings) === true) {
      _globals.settings = $.extend(true, {}, defaultSettings, settings);
    }
    else {
      _globals.settings = defaultSettings;
    }

    /* this object contains a number of functions to test for dependencies,
     * doesExist function should return TRUE if the library/browser/etc is present
     */
    _globals.dependencies = {
      /* check for jQuery 1.6+ to be present */
      "jquery1.6+": {
        doesExist: function () {
          var jqv, jqv_main, jqv_sub;
          if (window.jQuery) {
            jqv = jQuery().jquery.split(".");
            jqv_main = parseInt(jqv[0], 10);
            jqv_sub = parseInt(jqv[1], 10);
            if (jqv_main > 1 || (jqv_main === 1 && jqv_sub >= 6)) {
              return true;
            }
          }
          return false;
        },
        cdnUrl: "http://code.jquery.com/jquery-git1.js"
      }
    };
    _helper.checkDependencies();

    //this object holds all plugins
    _globals.plugins = {};

    /* register DOM elements
     * jQuerified elements start with $
     */
    _globals.$element = $(element);
    _globals.$attributeWrapper = _globals.$element.closest('.xmlJsonEditor_attribute_container');

    _globals.template = '<div class="maEditor_source"></div>';
    _globals.$matchTypeSelector = $('<select><option value="exact">' + Drupal.t('This is the complete answer.') + '</option><option value="part">' + Drupal.t('This is part of the answer.') + '</option></select>')

    /**
     * Init function
     **/
    publicObj.init = function () {
      _globals.$element.append(_globals.template);
      _globals.$element.append(_globals.$matchTypeSelector);
       _globals.$element.after('<p class="xmlEditorAttributeFeedback" style="margin-bottom: 0;">The condition as it is stored in the database:</p>');
      _globals.$sourceBox = _globals.$element.find('.maEditor_source');
      _globals.$input = $(cfg('input'));

      /* Add options */
      $.each(cfg('question_options'), function () {
        var $optionEl = getOptionElement(this.id, this.label, '');
        _globals.$sourceBox.append($optionEl);

      });

      // Add events to options, match type select and input
      _globals.$sourceBox.find('input[type=checkbox]').each(function () {
        var $input = $(this);
        $input.on('click', function () {
          updateAnswerInput();
          enableEditor();
        });
      });

      _globals.$matchTypeSelector.on('change', function () {
        updateAnswerInput();
      });

      _globals.$input.on('keyup', function () {
        window.clearTimeout(_globals.$input.data('maEditor_timeout'));
        var to = window.setTimeout(function () {
          updateQuestionGUI();
        }, 300);
        _globals.$input.data('maEditor_timeout', to);
      });

      /* Hide preset select */
      $('#xmlEditor_presets_select', _globals.$element.parent()).hide();

      updateQuestionGUI();
    };

    /**
     * Disables the editor.     *
     */
    function disableEditor() {
      $('#maEditor_feedback').remove();

      _globals.$element.addClass('xmlEditorAttributeFeedback_error');
      _globals.$element.after('<p id="maEditor_feedback" class="xmlJsonEditor_feedback_description" style="color:red;">This advanced condition is not (yet) supported by the editor. The editor might not display the condition correctly. Please use below input.</p>');

      $('.xmlEditorAttributeFeedback', _globals.$attributeWrapper).addClass('maEditor_visible');
      $('#xmlEditor_presets_select', _globals.$attributeWrapper).addClass('maEditor_visible');
      _globals.$input.addClass('maEditor_visible');
    }

    /**
     * Enables the editor.
     */
    function enableEditor() {
      $('#maEditor_feedback').remove();
      _globals.$element.removeClass('xmlEditorAttributeFeedback_error');
      $('.xmlEditorAttributeFeedback', _globals.$attributeWrapper).removeClass('maEditor_visible');
      $('#xmlEditor_presets_select', _globals.$attributeWrapper).removeClass('maEditor_visible');
      _globals.$input.removeClass('maEditor_visible');
    }

    /**
     * Creates an option jQuery DOM element.
     *
     * @param {string} dataId
     * @param {string} label
     * @param {string} classAttr
     * @returns {object}
     */
    function getOptionElement(dataId, label, classAttr) {
      classAttr = classAttr ? ' ' + classAttr : '';
      return $('<div class="maEditor_option' + classAttr + '"><input type="checkbox" name="maEditor" id="maEditor_' + dataId + '"><label for="maEditor_' + dataId + '">' + formatHTML(label) + '</label></div>');
    }

    /**
     * Updates the answer input based on the question GUI.
     */
    function updateAnswerInput() {
      var re_items = [];
      var matchType = _globals.$matchTypeSelector.val();

      _globals.$sourceBox.find('input[type=checkbox]').each(function () {
        var $input = $(this);
        if ($input.is(':checked')) {
          re_items.push($input.attr('id').replace(/maEditor_?/g, ''));
        }
        else if (matchType === 'part' && re_items[re_items.length - 1] !== '.*') {
          re_items.push('.*');
        }
      });

      // Fill input
      _globals.$input.val('^' + re_items.join('') + '$');

      // Keep input and editor in sync
      _globals.$input.trigger('change');
    }

    /**
     * Updates the question GUI based on the value of the input.
     */
    function updateQuestionGUI() {
      var shouldDisableEditor = false;
      var re = _globals.$input.val();
      var re_items = re.split('');
      var matchType = 'exact';
      $.each(re_items, function (i, re_item) {
        if (new RegExp('[0-9a-zA-Z\u00C0-\u017F]', 'i').test(re_item)) {
          $('#maEditor_' + re_item, _globals.$sourceBox).prop('checked', true);
        }
        else if (re_item === '.' || re_item === '*') {
          matchType = 'part';
        }
        else if (['$', '^'].indexOf(re_item) < 0) {
          shouldDisableEditor = true;
        }
      });

      // Set match type and disable editor if necessarry.
      _globals.$matchTypeSelector.val(matchType);
      if (shouldDisableEditor) {
        disableEditor();
      }
      else {
        enableEditor();
      }
    }

    /**
     * Returns a setting
     *
     * @param {string} paramName
     * @returns {mixed}
     */
    function cfg(paramName) {
      var returnVal;
      if (paramName === 'onlyOrder') {
        returnVal = parseInt(_globals.settings.onlyOrder, 10);
        returnVal = isNaN(returnVal) ? -1 : returnVal;
      }
      else {
        returnVal = _globals.settings[paramName];
      }

      return returnVal;
    }

    /**
     * Remove duplicates from a list.
     *
     * @param {object} $ul
     *  A jQuery DOM list object.
     */
    function sortableUniqueItems($ul) {
      var seen = {};
      $ul.find('li').each(function () {
        // Remove duplicates.
        var $li = $(this);
        var id = $li.attr('data-id');
        if (seen[id] === true) {
          $li.remove();
        }
        else {
          seen[id] = true;
        }
      });
    }

    /**
     * Format 'available items' sortable.
     */
    function formatAvailableItemsSortable() {
      // Make sure sortable has unique items.
      sortableUniqueItems(_globals.$sourceSortable);

      // Unset margin left set by formatTargetItemsSortable.
      _globals.$sourceSortable.find('li').css({"margin-left": ''});
    }

    /**
     * Format target item sortables.
     */
    function formatTargetItemsSortable() {
      // Deal with 'Only select, order of options does not matter'
      if (cfg('onlyOrder') === 2) {
        $(".maEditor_target_sortable").each(function () {
          sortableUniqueItems($(this));  // Make sure each target sortable has unique items.
        });
      }
    }

    /**
     * Formats HTML
     *
     * @param {string} html
     * @returns {string}
     *   The formatted contents.
     */
    function formatHTML(html) {
      /* Handle Media tags */
      var inlineTag = '', imgHTML = 'img', mediaObj, i;
      var html, styleAttr;
      var matches = html.match(/\[\[.*?\]\]/g);
      if (matches) {
        for (i = 0; i < matches.length; i++) {
          inlineTag = matches[i];
          inlineTag = inlineTag.replace('[[', '').replace(']]', '');
          mediaObj = JSON.parse(inlineTag);
          if (mediaObj && mediaObj.attributes && (mediaObj.attributes['data-src'] || mediaObj.attributes['src'])) {
            mediaObj.attributes['data-src'] = mediaObj.attributes['data-src'] ? mediaObj.attributes['data-src'] : mediaObj.attributes['src'];
            styleAttr = mediaObj.attributes.style ? ' style="' + mediaObj.attributes.style + '"' : '';
            imgHTML = '<img src="' + mediaObj.attributes['data-src'] + '" width="' + mediaObj.attributes['width'] + '" height="' + mediaObj.attributes['height'] + '"' + styleAttr + ' />';
          }
          html = html.replace(matches[i], imgHTML);
        }
      }
      return html;
    }

    /* initialize maEditor
     */
    if (_cdnFilesToBeLoaded.length === 0) {
      _helper.doInit();
    }
  };

  $.fn.maEditor = function (settings) {
    return this.each(function () {
      if (undefined === $(this).data("maEditor")) {
        var plugin = new $.maEditor(this, settings);
        $(this).data("maEditor", plugin);
      }
    });
  };
})(jQuery);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc