123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- /**
- * Yii JavaScript module.
- *
- * @link http://www.yiiframework.com/
- * @copyright Copyright (c) 2008 Yii Software LLC
- * @license http://www.yiiframework.com/license/
- * @author Qiang Xue <[email protected]>
- * @since 2.0
- */
- /**
- * yii is the root module for all Yii JavaScript modules.
- * It implements a mechanism of organizing JavaScript code in modules through the function "yii.initModule()".
- *
- * Each module should be named as "x.y.z", where "x" stands for the root module (for the Yii core code, this is "yii").
- *
- * A module may be structured as follows:
- *
- * ~~~
- * yii.sample = (function($) {
- * var pub = {
- * // whether this module is currently active. If false, init() will not be called for this module
- * // it will also not be called for all its child modules. If this property is undefined, it means true.
- * isActive: true,
- * init: function() {
- * // ... module initialization code go here ...
- * },
- *
- * // ... other public functions and properties go here ...
- * };
- *
- * // ... private functions and properties go here ...
- *
- * return pub;
- * })(jQuery);
- * ~~~
- *
- * Using this structure, you can define public and private functions/properties for a module.
- * Private functions/properties are only visible within the module, while public functions/properties
- * may be accessed outside of the module. For example, you can access "yii.sample.isActive".
- *
- * You must call "yii.initModule()" once for the root module of all your modules.
- */
- yii = (function ($) {
- var pub = {
- /**
- * List of scripts that can be loaded multiple times via AJAX requests. Each script can be represented
- * as either an absolute URL or a relative one.
- */
- reloadableScripts: [],
- /**
- * The selector for clickable elements that need to support confirmation and form submission.
- */
- clickableSelector: 'a, button, input[type="submit"], input[type="button"], input[type="reset"], input[type="image"]',
- /**
- * The selector for changeable elements that need to support confirmation and form submission.
- */
- changeableSelector: 'select, input, textarea',
- /**
- * @return string|undefined the CSRF variable name. Undefined is returned if CSRF validation is not enabled.
- */
- getCsrfVar: function () {
- return $('meta[name=csrf-var]').prop('content');
- },
- /**
- * @return string|undefined the CSRF token. Undefined is returned if CSRF validation is not enabled.
- */
- getCsrfToken: function () {
- return $('meta[name=csrf-token]').prop('content');
- },
- /**
- * Displays a confirmation dialog.
- * The default implementation simply displays a js confirmation dialog.
- * You may override this by setting `yii.confirm`.
- * @param message the confirmation message.
- * @return boolean whether the user confirms with the message in the dialog
- */
- confirm: function (message) {
- return confirm(message);
- },
- /**
- * Returns a value indicating whether to allow executing the action defined for the specified element.
- * This method recognizes the `data-confirm` attribute of the element and uses it
- * as the message in a confirmation dialog. The method will return true if this special attribute
- * is not defined or if the user confirms the message.
- * @param $e the jQuery representation of the element
- * @return boolean whether to allow executing the action defined for the specified element.
- */
- allowAction: function ($e) {
- var message = $e.data('confirm');
- return message === undefined || pub.confirm(message);
- },
- /**
- * Handles the action triggered by user.
- * This method recognizes the `data-method` attribute of the element. If the attribute exists,
- * the method will submit the form containing this element. If there is no containing form, a form
- * will be created and submitted using the method given by this attribute value (e.g. "post", "put").
- * For hyperlinks, the form action will take the value of the "href" attribute of the link.
- * For other elements, either the containing form action or the current page URL will be used
- * as the form action URL.
- *
- * If the `data-method` attribute is not defined, the default element action will be performed.
- *
- * @param $e the jQuery representation of the element
- * @return boolean whether to execute the default action for the element.
- */
- handleAction: function ($e) {
- var method = $e.data('method');
- if (method === undefined) {
- return true;
- }
- var $form = $e.closest('form');
- var newForm = !$form.length;
- if (newForm) {
- var action = $e.prop('href');
- if (!action || !action.match(/(^\/|:\/\/)/)) {
- action = window.location.href;
- }
- $form = $('<form method="' + method + '" action="' + action + '"></form>');
- var target = $e.prop('target');
- if (target) {
- $form.attr('target', target);
- }
- if (!method.match(/(get|post)/i)) {
- $form.append('<input name="_method" value="' + method + '" type="hidden">');
- }
- var csrfVar = pub.getCsrfVar();
- if (csrfVar) {
- $form.append('<input name="' + csrfVar + '" value="' + pub.getCsrfToken() + '" type="hidden">');
- }
- $form.hide().appendTo('body');
- }
- var activeFormData = $form.data('yiiActiveForm');
- if (activeFormData) {
- // remember who triggers the form submission. This is used by yii.activeForm.js
- activeFormData.submitObject = $e;
- }
- $form.trigger('submit');
- if (newForm) {
- $form.remove();
- }
- return false;
- },
- initModule: function (module) {
- if (module.isActive === undefined || module.isActive) {
- if ($.isFunction(module.init)) {
- module.init();
- }
- $.each(module, function () {
- if ($.isPlainObject(this)) {
- pub.initModule(this);
- }
- });
- }
- },
- init: function () {
- initCsrfHandler();
- initRedirectHandler();
- initScriptFilter();
- initDataMethods();
- }
- };
- function initRedirectHandler() {
- // handle AJAX redirection
- $(document).ajaxComplete(function (event, xhr, settings) {
- var url = xhr.getResponseHeader('X-Redirect');
- if (url) {
- window.location = url;
- }
- });
- }
- function initCsrfHandler() {
- // automatically send CSRF token for all AJAX requests
- $.ajaxPrefilter(function (options, originalOptions, xhr) {
- if (!options.crossDomain && pub.getCsrfVar()) {
- xhr.setRequestHeader('X-CSRF-Token', pub.getCsrfToken());
- }
- });
- }
- function initDataMethods() {
- var $document = $(document);
- // handle data-confirm and data-method for clickable elements
- $document.on('click.yii', pub.clickableSelector, function (event) {
- var $this = $(this);
- if (pub.allowAction($this)) {
- return pub.handleAction($this);
- } else {
- event.stopImmediatePropagation();
- return false;
- }
- });
- // handle data-confirm and data-method for changeable elements
- $document.on('change.yii', pub.changeableSelector, function (event) {
- var $this = $(this);
- if (pub.allowAction($this)) {
- return pub.handleAction($this);
- } else {
- event.stopImmediatePropagation();
- return false;
- }
- });
- }
- function initScriptFilter() {
- var hostInfo = location.protocol + '//' + location.host;
- var loadedScripts = $('script[src]').map(function () {
- return this.src.charAt(0) === '/' ? hostInfo + this.src : this.src;
- }).toArray();
- $.ajaxPrefilter('script', function (options, originalOptions, xhr) {
- var url = options.url.charAt(0) === '/' ? hostInfo + options.url : options.url;
- if ($.inArray(url, loadedScripts) === -1) {
- loadedScripts.push(url);
- } else {
- var found = $.inArray(url, $.map(pub.reloadableScripts, function (script) {
- return script.charAt(0) === '/' ? hostInfo + script : script;
- })) !== -1;
- if (!found) {
- xhr.abort();
- }
- }
- });
- }
- return pub;
- })(jQuery);
- jQuery(document).ready(function () {
- yii.initModule(yii);
- });
|