src/cm/media/js/lib/yui/yui_3.10.3/build/app-content/app-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('app-content', function (Y, NAME) {
       
     9 
       
    10 /**
       
    11 `Y.App` extension that provides pjax-style content fetching and handling.
       
    12 
       
    13 @module app
       
    14 @submodule app-content
       
    15 @since 3.7.0
       
    16 **/
       
    17 
       
    18 var PjaxContent = Y.PjaxContent;
       
    19 
       
    20 /**
       
    21 `Y.App` extension that provides pjax-style content fetching and handling.
       
    22 
       
    23 This makes it easy to fetch server rendered content for URLs using Ajax. The
       
    24 HTML content returned from the server will be view-ified and set as the app's
       
    25 main content, making it seamless to use a mixture of server and client rendered
       
    26 views.
       
    27 
       
    28 When the `"app-content"` module is used, it will automatically mix itself into
       
    29 `Y.App`, and it provides three main features:
       
    30 
       
    31   - **`Y.App.Content.route`**: A stack of middleware which forms a pjax-style
       
    32     content route.
       
    33 
       
    34   - **`loadContent()`**: Route middleware which load content from a server. This
       
    35     makes an Ajax request for the requested URL, parses the returned content and
       
    36     puts it on the route's response object.
       
    37 
       
    38   - **`showContent()`**: Method which provides an easy way to view-ify HTML
       
    39     content which should be shown as an app's active/visible view.
       
    40 
       
    41 The following is an example of how these features can be used:
       
    42 
       
    43     // Creates a new app and registers the `"post"` view.
       
    44     var app = new Y.App({
       
    45         views: {
       
    46             post: {type: Y.PostView}
       
    47         }
       
    48     });
       
    49 
       
    50     // Uses a simple server rendered content route for the About page.
       
    51     app.route('/about/', Y.App.Content.route);
       
    52 
       
    53     // Uses the `loadContent()` middleware to fetch the contents of the post
       
    54     // from the server and shows that content in a `"post"` view.
       
    55     app.route('/posts/:id/', 'loadContent', function (req, res, next) {
       
    56         this.showContent(res.content.node, {view: 'post'});
       
    57     });
       
    58 
       
    59 @class App.Content
       
    60 @uses PjaxContent
       
    61 @extensionfor App
       
    62 @since 3.7.0
       
    63 **/
       
    64 function AppContent() {
       
    65     PjaxContent.apply(this, arguments);
       
    66 }
       
    67 
       
    68 /**
       
    69 A stack of middleware which forms a pjax-style content route.
       
    70 
       
    71 This route will load the rendered HTML content from the server, then create and
       
    72 show a new view using those contents.
       
    73 
       
    74 @property route
       
    75 @type Array
       
    76 @static
       
    77 @since 3.7.0
       
    78 **/
       
    79 AppContent.route = ['loadContent', '_contentRoute'];
       
    80 
       
    81 AppContent.prototype = {
       
    82     // -- Public Methods -------------------------------------------------------
       
    83 
       
    84     /**
       
    85     Sets this app's `activeView` attribute using the specified `content`.
       
    86 
       
    87     This provides an easy way to view-ify HTML content which should be shown as
       
    88     this app's active/visible view. This method will determine the appropriate
       
    89     view `container` node based on the specified `content`. By default, a new
       
    90     `Y.View` instance will be created unless `options.view` is specified.
       
    91 
       
    92     Under the hood, this method calls the `showView()` method, so refer to its
       
    93     docs for more information.
       
    94 
       
    95     @method showContent
       
    96     @param {HTMLElement|Node|String} content The content to show, it may be
       
    97         provided as a selector string, a DOM element, or a `Y.Node` instance.
       
    98     @param {Object} [options] Optional objects containing any of the following
       
    99         properties in addition to any `showView()` options:
       
   100 
       
   101       @param {Object|String} [options.view] The name of a view defined in this
       
   102           app's `views`, or an object with the following properties:
       
   103 
       
   104         @param {String} options.view.name The name of a view defined in this
       
   105             app's `views`.
       
   106         @param {Object} [options.view.config] Optional configuration to use when
       
   107             creating the new view instance. This config object can also be used
       
   108             to update an existing or preserved view's attributes when
       
   109             `options.update` is `true`. **Note:** If a `container` is specified,
       
   110             it will be overridden by the `content` specified in the first
       
   111             argument.
       
   112 
       
   113     @param {Function} [callback] Optional callback function to call after the
       
   114         new `activeView` is ready to use. **Note:** this will override
       
   115         `options.callback` and it can be specified as either the second or third
       
   116         argument. The function will be passed the following:
       
   117 
       
   118       @param {View} callback.view A reference to the new `activeView`.
       
   119 
       
   120     @since 3.7.0
       
   121     @see App.showView()
       
   122     **/
       
   123     showContent: function (content, options, callback) {
       
   124         // Makes sure we have a node instance, and will query selector strings.
       
   125         content = Y.one(content);
       
   126 
       
   127         // Support the callback function being either the second or third arg.
       
   128         if (typeof options === 'function') {
       
   129             options  = {callback: options};
       
   130             callback = null;
       
   131         }
       
   132 
       
   133         // Mix in default option to *not* render the view because presumably we
       
   134         // have pre-rendered content here. This also creates a copy so we can
       
   135         // modify the object.
       
   136         options = Y.merge({render: false}, options);
       
   137 
       
   138         var view       = options.view || '',
       
   139             viewName   = typeof view === 'string' ? view : view.name,
       
   140             viewConfig = typeof view !== 'string' ? view.config : {},
       
   141             viewInfo   = this.getViewInfo(viewName),
       
   142             container, template, type, ViewConstructor;
       
   143 
       
   144         // Remove `view` from the `options` which will be passed along to the
       
   145         // `showView()` method.
       
   146         delete options.view;
       
   147 
       
   148         // When the specified `content` is a document fragment, we want to see
       
   149         // if it only contains a single node, and use that as the content. This
       
   150         // checks `childNodes` which will include text nodes.
       
   151         if (content && content.isFragment() &&
       
   152                 content.get('childNodes').size() === 1) {
       
   153 
       
   154             content = content.get('firstChild');
       
   155         }
       
   156 
       
   157         // When the `content` is an element node (`nodeType` 1), we can use it
       
   158         // as-is for the `container`. Otherwise, we'll construct a new container
       
   159         // based on the `options.view`'s `containerTemplate`.
       
   160         if (content && content.get('nodeType') === 1) {
       
   161             container = content;
       
   162         } else {
       
   163             type = (viewInfo && viewInfo.type) || Y.View;
       
   164 
       
   165             // Looks for a namespaced constructor function on `Y`.
       
   166             ViewConstructor = typeof type === 'string' ?
       
   167                     Y.Object.getValue(Y, type.split('.')) : type;
       
   168 
       
   169             // Find the correct node template for the view.
       
   170             template  = ViewConstructor.prototype.containerTemplate;
       
   171             container = Y.Node.create(template);
       
   172 
       
   173             // Append the document fragment to the newly created `container`
       
   174             // node. This is the worst case where we have to create a wrapper
       
   175             // node around the `content`.
       
   176             container.append(content);
       
   177         }
       
   178 
       
   179         // Makes sure the view is created using _our_ `container` node.
       
   180         viewConfig = Y.merge(viewConfig, {container: container});
       
   181 
       
   182         // Finally switch to the new `activeView`. We want to make sure `view`
       
   183         // is a string if it's falsy, that way a new view will be created.
       
   184         return this.showView(viewName, viewConfig, options, callback);
       
   185     },
       
   186 
       
   187     // -- Protected Methods ----------------------------------------------------
       
   188 
       
   189     /**
       
   190     Provides a default content route which will show a server rendered view.
       
   191 
       
   192     **Note:** This route callback assumes that it's called after the
       
   193     `loadContent()` middleware.
       
   194 
       
   195     @method _contentRoute
       
   196     @param {Object} req Request object.
       
   197     @param {Object} res Response Object.
       
   198     @param {Function} next Function to pass control to the next route callback.
       
   199     @protected
       
   200     @since 3.7.0
       
   201     @see Y.App.Content.route
       
   202     **/
       
   203     _contentRoute: function (req, res, next) {
       
   204         var content = res.content,
       
   205             doc     = Y.config.doc,
       
   206             activeViewHandle;
       
   207 
       
   208         // We must have some content to work with.
       
   209         if (!(content && content.node)) { return next(); }
       
   210 
       
   211         if (content.title && doc) {
       
   212             // Make sure the `activeView` does actually change before we go
       
   213             // messing with the page title.
       
   214             activeViewHandle = this.onceAfter('activeViewChange', function () {
       
   215                 doc.title = content.title;
       
   216             });
       
   217         }
       
   218 
       
   219         this.showContent(content.node);
       
   220 
       
   221         // Detach the handle just in case.
       
   222         if (activeViewHandle) {
       
   223             activeViewHandle.detach();
       
   224         }
       
   225 
       
   226         next();
       
   227     }
       
   228 };
       
   229 
       
   230 // Mix statics.
       
   231 AppContent.ATTRS = Y.Attribute.protectAttrs(PjaxContent.ATTRS);
       
   232 
       
   233 // Mix prototype.
       
   234 Y.mix(AppContent, PjaxContent, false, null, 1);
       
   235 
       
   236 // -- Namespace ----------------------------------------------------------------
       
   237 Y.App.Content = AppContent;
       
   238 Y.Base.mix(Y.App, [AppContent]);
       
   239 
       
   240 
       
   241 }, '3.10.3', {"requires": ["app-base", "pjax-content"]});