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