src/cm/media/js/lib/yui/yui_3.10.3/build/pjax-content/pjax-content-debug.js
changeset 525 89ef5ed3c48b
equal deleted inserted replaced
524:322d0feea350 525:89ef5ed3c48b
       
     1 /*
       
     2 YUI 3.10.3 (build 2fb5187)
       
     3 Copyright 2013 Yahoo! Inc. All rights reserved.
       
     4 Licensed under the BSD License.
       
     5 http://yuilibrary.com/license/
       
     6 */
       
     7 
       
     8 YUI.add('pjax-content', function (Y, NAME) {
       
     9 
       
    10 /**
       
    11 `Y.Router` extension that provides the content fetching and handling needed to
       
    12 implement the standard pjax (HTMP5 pushState + Ajax) functionality.
       
    13 
       
    14 @module pjax
       
    15 @submodule pjax-content
       
    16 @since 3.7.0
       
    17 **/
       
    18 
       
    19 /**
       
    20 `Y.Router` extension that provides the content fetching and handling needed to
       
    21 implement the standard pjax (HTMP5 pushState + Ajax) functionality.
       
    22 
       
    23 This makes it easy to fetch server rendered content for URLs using Ajax. By
       
    24 helping the router to fulfill the "request" for the content you can avoid full
       
    25 page loads.
       
    26 
       
    27 The `PjaxContent` class isn't useful on its own, but can be mixed into a
       
    28 `Router`-based class along with the `PjaxBase` class to add Pjax functionality
       
    29 to that Router. For a pre-made standalone Pjax router, see the `Pjax` class.
       
    30 
       
    31     var MyRouter = Y.Base.create('myRouter', Y.Router, [
       
    32         Y.PjaxBase,
       
    33         Y.PjaxContent
       
    34     ], {
       
    35         // ...
       
    36     });
       
    37 
       
    38 @class PjaxContent
       
    39 @extensionfor Router
       
    40 @since 3.7.0
       
    41 **/
       
    42 function PjaxContent() {}
       
    43 
       
    44 PjaxContent.prototype = {
       
    45     // -- Public Methods -------------------------------------------------------
       
    46 
       
    47     /**
       
    48     Extracts and returns the relevant HTML content from an Ajax response. The
       
    49     content is extracted using the `contentSelector` attribute as a CSS
       
    50     selector. If `contentSelector` is `null`, the entire response will be
       
    51     returned.
       
    52 
       
    53     The return value is an object containing two properties:
       
    54 
       
    55       * `node`: A `Y.Node` instance for a document fragment containing the
       
    56         extracted HTML content.
       
    57 
       
    58       * `title`: The title of the HTML page, if any, extracted using the
       
    59         `titleSelector` attribute (which defaults to looking for a `<title>`
       
    60         element). If `titleSelector` is not set or if a title could not be
       
    61         found, this property will be `undefined`.
       
    62 
       
    63     @method getContent
       
    64     @param {String} responseText Raw Ajax response text.
       
    65     @return {Object} Content object with the properties described above.
       
    66     @since 3.5.0
       
    67     **/
       
    68     getContent: function (responseText) {
       
    69         var content         = {},
       
    70             contentSelector = this.get('contentSelector'),
       
    71             frag            = Y.Node.create(responseText || ''),
       
    72             titleSelector   = this.get('titleSelector'),
       
    73             titleNode;
       
    74 
       
    75         if (contentSelector && frag) {
       
    76             content.node = frag.all(contentSelector).toFrag();
       
    77         } else {
       
    78             content.node = frag;
       
    79         }
       
    80 
       
    81         if (titleSelector && frag) {
       
    82             titleNode = frag.one(titleSelector);
       
    83 
       
    84             if (titleNode) {
       
    85                 content.title = titleNode.get('text');
       
    86             }
       
    87         }
       
    88 
       
    89         return content;
       
    90     },
       
    91 
       
    92     /**
       
    93     Pjax route middleware to load content from a server. This makes an Ajax
       
    94     request for the requested URL, parses the returned content and puts it on
       
    95     the route's response object.
       
    96 
       
    97     This is route middleware and not intended to be the final callback for a
       
    98     route. This will add the following information to the route's request and
       
    99     response objects:
       
   100 
       
   101       - `req.ioURL`: The full URL that was used to make the `Y.io()` XHR. This
       
   102         may contain `"pjax=1"` if the `addPjaxParam` option is set.
       
   103 
       
   104       - `res.content`: An object containing `node` and `title` properties for
       
   105         the content extracted from the server's response. See `getContent()` for
       
   106         more details.
       
   107 
       
   108       - `res.ioResponse`: The full `Y.io()` response object. This is useful if
       
   109         you need access to the XHR's response `status` or HTTP headers.
       
   110 
       
   111     @example
       
   112         router.route('/foo/', 'loadContent', function (req, res, next) {
       
   113             Y.one('container').setHTML(res.content.node);
       
   114             Y.config.doc.title = res.content.title;
       
   115         });
       
   116 
       
   117     @method loadContent
       
   118     @param {Object} req Request object.
       
   119     @param {Object} res Response Object.
       
   120     @param {Function} next Function to pass control to the next route callback.
       
   121     @since 3.7.0
       
   122     @see Router.route()
       
   123     **/
       
   124     loadContent: function (req, res, next) {
       
   125         var url = req.url;
       
   126 
       
   127         // If there's an outstanding request, abort it.
       
   128         if (this._request) {
       
   129             this._request.abort();
       
   130         }
       
   131 
       
   132         // Add a 'pjax=1' query parameter if enabled.
       
   133         if (this.get('addPjaxParam')) {
       
   134             // Captures the path with query, and hash parts of the URL. Then
       
   135             // properly injects the "pjax=1" query param in the right place,
       
   136             // before any hash fragment, and returns the updated URL.
       
   137             url = url.replace(/([^#]*)(#.*)?$/, function (match, path, hash) {
       
   138                 path += (path.indexOf('?') > -1 ? '&' : '?') + 'pjax=1';
       
   139                 return path + (hash || '');
       
   140             });
       
   141         }
       
   142 
       
   143         // Send a request.
       
   144         this._request = Y.io(url, {
       
   145             'arguments': {
       
   146                 route: {
       
   147                     req : req,
       
   148                     res : res,
       
   149                     next: next
       
   150                 },
       
   151 
       
   152                 url: url
       
   153             },
       
   154 
       
   155             context: this,
       
   156             headers: {'X-PJAX': 'true'},
       
   157             timeout: this.get('timeout'),
       
   158 
       
   159             on: {
       
   160                 complete: this._onPjaxIOComplete,
       
   161                 end     : this._onPjaxIOEnd
       
   162             }
       
   163         });
       
   164     },
       
   165 
       
   166     // -- Event Handlers -------------------------------------------------------
       
   167 
       
   168     /**
       
   169     Handles IO complete events.
       
   170 
       
   171     This parses the content from the `Y.io()` response and puts it on the
       
   172     route's response object.
       
   173 
       
   174     @method _onPjaxIOComplete
       
   175     @param {String} id The `Y.io` transaction id.
       
   176     @param {Object} ioResponse The `Y.io` response object.
       
   177     @param {Object} details Extra details carried through from `loadContent()`.
       
   178     @protected
       
   179     @since 3.7.0
       
   180     **/
       
   181     _onPjaxIOComplete: function (id, ioResponse, details) {
       
   182         var content = this.getContent(ioResponse.responseText),
       
   183             route   = details.route,
       
   184             req     = route.req,
       
   185             res     = route.res;
       
   186 
       
   187         // Put the URL requested through `Y.io` on the route's `req` object.
       
   188         req.ioURL = details.url;
       
   189 
       
   190         // Put the parsed content and `Y.io` response object on the route's
       
   191         // `res` object.
       
   192         res.content    = content;
       
   193         res.ioResponse = ioResponse;
       
   194 
       
   195         route.next();
       
   196     },
       
   197 
       
   198     /**
       
   199     Handles IO end events.
       
   200 
       
   201     @method _onPjaxIOEnd
       
   202     @param {String} id The `Y.io` transaction id.
       
   203     @param {Object} details Extra details carried through from `loadContent()`.
       
   204     @protected
       
   205     @since 3.5.0
       
   206     **/
       
   207     _onPjaxIOEnd: function () {
       
   208         this._request = null;
       
   209     }
       
   210 };
       
   211 
       
   212 PjaxContent.ATTRS = {
       
   213     /**
       
   214     If `true`, a "pjax=1" query parameter will be appended to all URLs
       
   215     requested via Pjax.
       
   216 
       
   217     Browsers ignore HTTP request headers when caching content, so if the
       
   218     same URL is used to request a partial Pjax page and a full page, the
       
   219     browser will cache them under the same key and may later load the
       
   220     cached partial page when the user actually requests a full page (or vice
       
   221     versa).
       
   222 
       
   223     To prevent this, we can add a bogus query parameter to the URL so that
       
   224     Pjax URLs will always be cached separately from non-Pjax URLs.
       
   225 
       
   226     @attribute addPjaxParam
       
   227     @type Boolean
       
   228     @default true
       
   229     @since 3.5.0
       
   230     **/
       
   231     addPjaxParam: {
       
   232         value: true
       
   233     },
       
   234 
       
   235     /**
       
   236     CSS selector used to extract a specific portion of the content of a page
       
   237     loaded via Pjax.
       
   238 
       
   239     For example, if you wanted to load the page `example.html` but only use
       
   240     the content within an element with the id "pjax-content", you'd set
       
   241     `contentSelector` to "#pjax-content".
       
   242 
       
   243     If not set, the entire page will be used.
       
   244 
       
   245     @attribute contentSelector
       
   246     @type String
       
   247     @default null
       
   248     @since 3.5.0
       
   249     **/
       
   250     contentSelector: {
       
   251         value: null
       
   252     },
       
   253 
       
   254     /**
       
   255     CSS selector used to extract a page title from the content of a page
       
   256     loaded via Pjax.
       
   257 
       
   258     By default this is set to extract the title from the `<title>` element,
       
   259     but you could customize it to extract the title from an `<h1>`, or from
       
   260     any other element, if that's more appropriate for the content you're
       
   261     loading.
       
   262 
       
   263     @attribute titleSelector
       
   264     @type String
       
   265     @default "title"
       
   266     @since 3.5.0
       
   267     **/
       
   268     titleSelector: {
       
   269         value: 'title'
       
   270     },
       
   271 
       
   272     /**
       
   273     Time in milliseconds after which an Ajax request should time out.
       
   274 
       
   275     @attribute timeout
       
   276     @type Number
       
   277     @default 30000
       
   278     @since 3.5.0
       
   279     **/
       
   280     timeout: {
       
   281         value: 30000
       
   282     }
       
   283 };
       
   284 
       
   285 Y.PjaxContent = PjaxContent;
       
   286 
       
   287 
       
   288 }, '3.10.3', {"requires": ["io-base", "node-base", "router"]});