ICEfaces
  1. ICEfaces
  2. ICE-6490

Integrate the YUI Loader into the ACE platform

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.0.1
    • Component/s: ACE-Components
    • Labels:
      None
    • Environment:
      ICEfaces Advanced Component Environment (ACE), YUI 3.3
    • Affects:
      Documentation (User Guide, Ref. Guide, etc.), Compatibility/Configuration

      Description

      In order to facilitate the improvements listed below we need to replace the existing static resource dependency declarations used by the ACE components with a (potentially customized) version of the YUI Loader, which is a sophisticated solution for managing the dependencies and loading of YUI JS files.

      - Reduce overhead and fragility caused by the need to statically declare all YUI JS file dependencies in each ACE component, including parent dependencies within the YUI JS stack. This will make upgrading to new YUI releases much simpler, and creating and maintaining ACE components less tedious.
      - Provide flexibility with regard to the JS loading strategy being used. The Loader supports different optimization strategies that can be chosen/configured at runtime, instead of development time. This should avoid the necessity to pre-load all the YUI JS required for each component initially, instead allowing a base-level of JS to be loaded and then additional JS as required by components as they are initialized for faster initial page loads, smaller overall JS HTTP transmissions over the wire.
      - Provide the ability to easily build and deploy an application using debug, or minified JS files.
      - Provide an extension point to potentially load the YUI JS into a custom namespace.

      The current YUI release level is 3.3, which includes improvements to the Loader, and is the one we should target for this work.

        Issue Links

          Activity

          Hide
          Mark Collette added a comment - - edited

          Found my notes on doing this. It shows using YUI 3 to load YUI 2 libraries, as well as how to use the loader in general, instead of numerous static javascript references in our Meta classes.

          http://jira.icefaces.org/browse/ICE-6273

          Show
          Mark Collette added a comment - - edited Found my notes on doing this. It shows using YUI 3 to load YUI 2 libraries, as well as how to use the loader in general, instead of numerous static javascript references in our Meta classes. http://jira.icefaces.org/browse/ICE-6273
          Hide
          Arturo Zambrano added a comment -

          Some preliminary observations...

          The good news is that the YUI3 loader accepts the 'base' attribute that specifies the base path to locate dependencies. So, that resources can be dynamically loaded from the same server the application runs on, and not from Yahoo's servers.

          Another good point is that the YUI3 loader has intrinsic support for loading YUI2 dependencies.

          Another thing is that it's also possible to declare and load custom modules. So, potentially, we could remove all @ResourceDependency annotations and only load a common, base js file to dynamically load all resources, including css.

          The challenging part at this point is that the 'base' attribute assumes that the URL is in the standard format and not in the JSF format. So, we might have to extend the YUI object or maybe modify the source code. The function that generates the resource URLs is declared as a prototype function of YUI.Loader, so, we might get away with wrapping the original function inside our custom function that appends ".jsf" to the URL, etc.

          Show
          Arturo Zambrano added a comment - Some preliminary observations... The good news is that the YUI3 loader accepts the 'base' attribute that specifies the base path to locate dependencies. So, that resources can be dynamically loaded from the same server the application runs on, and not from Yahoo's servers. Another good point is that the YUI3 loader has intrinsic support for loading YUI2 dependencies. Another thing is that it's also possible to declare and load custom modules. So, potentially, we could remove all @ResourceDependency annotations and only load a common, base js file to dynamically load all resources, including css. The challenging part at this point is that the 'base' attribute assumes that the URL is in the standard format and not in the JSF format. So, we might have to extend the YUI object or maybe modify the source code. The function that generates the resource URLs is declared as a prototype function of YUI.Loader, so, we might get away with wrapping the original function inside our custom function that appends ".jsf" to the URL, etc.
          Hide
          Arturo Zambrano added a comment -

          I managed to dynamically load YUI resources from the local server without using @ResourceDependency's and with the correct JSF URL format. It wasn't necessary to modify the original YUI source code. I did this for slider. Now, I'm investigating how to do it for YUI2 components (using the YUI3 loader).

          Show
          Arturo Zambrano added a comment - I managed to dynamically load YUI resources from the local server without using @ResourceDependency's and with the correct JSF URL format. It wasn't necessary to modify the original YUI source code. I did this for slider. Now, I'm investigating how to do it for YUI2 components (using the YUI3 loader).
          Hide
          Arturo Zambrano added a comment -

          I committed some code, and this is what I've done and found out...

          • It's very easy and straight forward to dynamically load YUI3 resources from a local server. This was tested with slider, and all that needs to be done is to specify a path in the 'base' option of the YUI instance.
          • In order to produce URLs in the JSF format, it is enough to override YUI.Loader.prototype._url with a function that appends ".jsf" to the original result, as shown in slider.js.
          • @MandatoryResourceComponent annotations were commented out from all renderers.
          • All YUI @ResourceDependency's (except yui-min) were removed from slider, tabset, and animation.
          • Loading YUI2 from YUI3 is not that easy, as explained below.
          • First, the YUI3 loader does not really have dependency resolution logic for YUI2. All it has is a pre-configured 'group' for YUI2 that downloads files from Yahoo's servers. The YUI3 loader only contains dependency resolution logic for YUI3 components (in the last part of loader.js). This was checked in versions 3.1.1 and 3.3.0.
          • Second, The YUI2 files downloaded from YUI3 (referred to as 2in3), are slightly modified YUI2 source files. The extra code makes sure that YUI2 components also work in a sandboxed way (i.e. there will be no global YAHOO object). Part of those modifications are the actual dependencies for that file. This means that YUI2 dependencies are simply hard-coded in these modified versions. An example of this code looks like this:

          YUI.add('yui2-tabview', function(Y) {
          if (Y.YUI2)

          { var YAHOO = Y.YUI2; }

          /* original code */

          if (!Y.YUI2)

          { Y.YUI2 = YAHOO; }

          if (!YAHOO._activ && YAHOO.util.Event)

          { YAHOO._activ = true; YAHOO.util.Event._load(); }

          }, '2.8.0' ,

          {"requires": ["yui2-yahoo", "yui2-dom", "yui2-event", "yui2-skin-sam-tabview", "yui2-element"], "optional": ["yui2-connection"]}

          );

          • Thus, the dependency resolution 'logic' for 2in3 only works if the resources are downloaded from Yahoo's servers (because the dependencies are hard-coded.
          • It is possible to manually create a custom 'group' setting in the YUI3 loader to download YUI2 resources from a local server, but there would not be automatic dependency resolution. We would have to hard-code all dependencies. The code to do this was committed but is commented out.

          These are two possible solutions:

          • Do the job of manually downloading from Yahoo server's every 2in3 modified source file and create a new resource library. Then, we can just create a custom 'group' setting in the YUI3 loader to access these files.
          • Dynamically load the YUI2 loader from YUI3, and from there let the YUI2 loader automatically resolve dependencies of components, since the YUI2 loader does have dependency resolution logic for YUI2 components (around the middle of yuiloader.js).

          The only difference between these two solutions is that in the first solution the YUI2 code would be sandboxed (i.e. no global YAHOO object), while this wouldn't be the case in the second solution.

          Show
          Arturo Zambrano added a comment - I committed some code, and this is what I've done and found out... It's very easy and straight forward to dynamically load YUI3 resources from a local server. This was tested with slider, and all that needs to be done is to specify a path in the 'base' option of the YUI instance. In order to produce URLs in the JSF format, it is enough to override YUI.Loader.prototype._url with a function that appends ".jsf" to the original result, as shown in slider.js. @MandatoryResourceComponent annotations were commented out from all renderers. All YUI @ResourceDependency's (except yui-min) were removed from slider, tabset, and animation. Loading YUI2 from YUI3 is not that easy, as explained below. First, the YUI3 loader does not really have dependency resolution logic for YUI2. All it has is a pre-configured 'group' for YUI2 that downloads files from Yahoo's servers. The YUI3 loader only contains dependency resolution logic for YUI3 components (in the last part of loader.js). This was checked in versions 3.1.1 and 3.3.0. Second, The YUI2 files downloaded from YUI3 (referred to as 2in3), are slightly modified YUI2 source files. The extra code makes sure that YUI2 components also work in a sandboxed way (i.e. there will be no global YAHOO object). Part of those modifications are the actual dependencies for that file. This means that YUI2 dependencies are simply hard-coded in these modified versions. An example of this code looks like this: YUI.add('yui2-tabview', function(Y) { if (Y.YUI2) { var YAHOO = Y.YUI2; } /* original code */ if (!Y.YUI2) { Y.YUI2 = YAHOO; } if (!YAHOO._activ && YAHOO.util.Event) { YAHOO._activ = true; YAHOO.util.Event._load(); } }, '2.8.0' , {"requires": ["yui2-yahoo", "yui2-dom", "yui2-event", "yui2-skin-sam-tabview", "yui2-element"], "optional": ["yui2-connection"]} ); Thus, the dependency resolution 'logic' for 2in3 only works if the resources are downloaded from Yahoo's servers (because the dependencies are hard-coded. It is possible to manually create a custom 'group' setting in the YUI3 loader to download YUI2 resources from a local server, but there would not be automatic dependency resolution. We would have to hard-code all dependencies. The code to do this was committed but is commented out. These are two possible solutions: Do the job of manually downloading from Yahoo server's every 2in3 modified source file and create a new resource library. Then, we can just create a custom 'group' setting in the YUI3 loader to access these files. Dynamically load the YUI2 loader from YUI3, and from there let the YUI2 loader automatically resolve dependencies of components, since the YUI2 loader does have dependency resolution logic for YUI2 components (around the middle of yuiloader.js). The only difference between these two solutions is that in the first solution the YUI2 code would be sandboxed (i.e. no global YAHOO object), while this wouldn't be the case in the second solution.
          Hide
          Mark Collette added a comment -

          > Second, The YUI2 files downloaded from YUI3 (referred to as 2in3), are slightly modified YUI2 source files.

          re we sure that these modified YUI2 files do not exist in our YUI3 distribution, and are not the same as the version of YUI2 that we currently have? Would we actually have to manually download every file, or is there some archive of them, or cvs/svn access to them?

          Show
          Mark Collette added a comment - > Second, The YUI2 files downloaded from YUI3 (referred to as 2in3), are slightly modified YUI2 source files. re we sure that these modified YUI2 files do not exist in our YUI3 distribution, and are not the same as the version of YUI2 that we currently have? Would we actually have to manually download every file, or is there some archive of them, or cvs/svn access to them?
          Hide
          Arturo Zambrano added a comment -

          These modified files do not already exist in our current YUI distributions (i.e. 2.8.1 and 3.1.1) nor in the latest 3.3.0 distribution. The URL used for these wrapper files is something like this

          http://yui.yahooapis.com/2in3.1/2.8.0/build/yui2-tabview/yui2-tabview-min.js

          ...so our distributions would have to have directories named like 'yui2-tabview' at the same level as the other modules, and this is not the case. I also made a full text search of the two distributions and I couldn't find some key strings like "Y.YUI2" that appear in the wrapper files.

          I found out that 2in3 is a completely separate project, and the good news is that it's possible to download all these wrapper files in a single zip file. This is the link where we can download the file:

          https://github.com/yui/2in3/tree/master/dist/2.8.2/build

          I already downloaded the file and noticed that it contains wrapper files for various versions of YUI2, up to 2.8.1. The original code is always the same, I made a careful comparison, and the only things that change are a couple of strings with version information. So, basically the original code is just wrapped inside a snippet of code, like the one shown above, to make it work with YUI3.

          So, I suppose that what we have to do is just to add this 2in3 project to our resource library.

          Show
          Arturo Zambrano added a comment - These modified files do not already exist in our current YUI distributions (i.e. 2.8.1 and 3.1.1) nor in the latest 3.3.0 distribution. The URL used for these wrapper files is something like this http://yui.yahooapis.com/2in3.1/2.8.0/build/yui2-tabview/yui2-tabview-min.js ...so our distributions would have to have directories named like 'yui2-tabview' at the same level as the other modules, and this is not the case. I also made a full text search of the two distributions and I couldn't find some key strings like "Y.YUI2" that appear in the wrapper files. I found out that 2in3 is a completely separate project, and the good news is that it's possible to download all these wrapper files in a single zip file. This is the link where we can download the file: https://github.com/yui/2in3/tree/master/dist/2.8.2/build I already downloaded the file and noticed that it contains wrapper files for various versions of YUI2, up to 2.8.1. The original code is always the same, I made a careful comparison, and the only things that change are a couple of strings with version information. So, basically the original code is just wrapped inside a snippet of code, like the one shown above, to make it work with YUI3. So, I suppose that what we have to do is just to add this 2in3 project to our resource library.
          Hide
          Mark Collette added a comment -

          I think, when I first read about 2in3, that I mistook their explanation of working with the latest 2.8 to mean that it was in the actual YUI code-base. Looks like these are their private patches. As long as it's all the same license, it should be ok.

          Show
          Mark Collette added a comment - I think, when I first read about 2in3, that I mistook their explanation of working with the latest 2.8 to mean that it was in the actual YUI code-base. Looks like these are their private patches. As long as it's all the same license, it should be ok.
          Hide
          Ken Fyten added a comment -

          Art reports:

          These are the issues I'm still working on:

          • The calendar component taking a while to re-render after selecting a date when single submit is enabled.
          • JS error in the animation page of the showcase in IE.
          • Logger issues. This is just a matter of replacing calls to YAHOO.log() with ice.log() if there are no objections.
          • Placing YUI loader resources in head or body? I made a test and it's possible to place the YUI loader JS in the body, either at the beginning or at the end of the body. There's just a JS error with our code, but I could see the YUI loader dynamically loading all the needed resources. I'll try to fix that error.
          • Implications of 2in3 on skinning.
          Show
          Ken Fyten added a comment - Art reports: These are the issues I'm still working on: The calendar component taking a while to re-render after selecting a date when single submit is enabled. JS error in the animation page of the showcase in IE. Logger issues. This is just a matter of replacing calls to YAHOO.log() with ice.log() if there are no objections. Placing YUI loader resources in head or body? I made a test and it's possible to place the YUI loader JS in the body, either at the beginning or at the end of the body. There's just a JS error with our code, but I could see the YUI loader dynamically loading all the needed resources. I'll try to fix that error. Implications of 2in3 on skinning.
          Hide
          Ken Fyten added a comment -

          Since this seems to be working out well we'll go ahead and pull this change into the IF 2.0.1 release, which means we only have a few days to resolve these issues. See my notes below:

          • The calendar component taking a while to re-render after selecting a date when single submit is enabled.
            --> I'll review but low priority for now.
          • JS error in the animation page of the showcase in IE.
            ---> Needs investigation, Mark will look at this when he can.
          • Logger issues. This is just a matter of replacing calls to YAHOO.log() with ice.log() if there are no objections.
            ---> For 2.0.1, just comment out the log statements (Art). We will revisit the log strategy for 2.1.
          • Placing YUI loader resources in head or body? I made a test and it's possible to place the YUI loader JS in the body, either at the beginning or at the end of the body. There's just a JS error with our code, but I could see the YUI loader dynamically loading all the needed resources. I'll try to fix that error.
            ---> Deferred to 2.1, for 2.0.1 we'll live with keeping it in the head.
          • Implications of 2in3 on skinning.
            ---> Need Art to resolve these asap.
          Show
          Ken Fyten added a comment - Since this seems to be working out well we'll go ahead and pull this change into the IF 2.0.1 release, which means we only have a few days to resolve these issues. See my notes below: The calendar component taking a while to re-render after selecting a date when single submit is enabled. --> I'll review but low priority for now. JS error in the animation page of the showcase in IE. ---> Needs investigation, Mark will look at this when he can. Logger issues. This is just a matter of replacing calls to YAHOO.log() with ice.log() if there are no objections. ---> For 2.0.1, just comment out the log statements (Art). We will revisit the log strategy for 2.1. Placing YUI loader resources in head or body? I made a test and it's possible to place the YUI loader JS in the body, either at the beginning or at the end of the body. There's just a JS error with our code, but I could see the YUI loader dynamically loading all the needed resources. I'll try to fix that error. ---> Deferred to 2.1, for 2.0.1 we'll live with keeping it in the head. Implications of 2in3 on skinning. ---> Need Art to resolve these asap.
          Hide
          Mark Collette added a comment -

          Added test code for using ace-showcase as a single page application, so that testing of postbacks with the YUI loader could happen. Had to re-enable MandatoryResourceComponent annotations for things to work.

          Subversion 24170

          Show
          Mark Collette added a comment - Added test code for using ace-showcase as a single page application, so that testing of postbacks with the YUI loader could happen. Had to re-enable MandatoryResourceComponent annotations for things to work. Subversion 24170
          Hide
          Mark Collette added a comment -

          Changed the ace showcase app so that if you go to single.jsf you get the single page app view, and if you go to main.jsf then you get the multi-page app view. That way we can easily test and demonstrate both scenarios.

          For now just made the ant build include all of yui/2in3, so I wouldn't worry about accidentally breaking anything by excluding too much.

          I ran into an issue where if you use ace/showcase/single.jsf the servlet engine adds jsessionid to every url on the first render, so the code in component.js that parses out the base address for yui will get confused. It looks like we need to refine the regex to accomodate the presence of jsessionid.

          Also, we should probably not rely on the .jsf extension being in the url, since applications could use anything for their servlet mapping.

          Tried solving the "yuiComp is undefined" exception, but haven't succeeded so far, so made it just skip over setting the properties for now. This seems to only affect tabSet, sometimes. I'm going to try re-sequencing some of the code so that all the use statements happen before ondomready. But I just wanted to commit everything before trying experiments. I'll also re-examine my theory of mis-matched braces in our tabset javascript code.

          Found that our CSS files were still referencing yui/2_8_1 which was breaking the tabSet pre-styling and also may have affected the buttons.

          Here's the list of outstanding issues, in order of importance:

          • tabSetProxy cancelOnInvalid="true" not working
          • Javascript exception yuiComp. Temporarily worked around with return
          • Regex not handling jsessionid and hardcoding .jsf extension
          • Not fine grained 2in3 jar inclusion

          Subversion 24206

          Show
          Mark Collette added a comment - Changed the ace showcase app so that if you go to single.jsf you get the single page app view, and if you go to main.jsf then you get the multi-page app view. That way we can easily test and demonstrate both scenarios. For now just made the ant build include all of yui/2in3, so I wouldn't worry about accidentally breaking anything by excluding too much. I ran into an issue where if you use ace/showcase/single.jsf the servlet engine adds jsessionid to every url on the first render, so the code in component.js that parses out the base address for yui will get confused. It looks like we need to refine the regex to accomodate the presence of jsessionid. Also, we should probably not rely on the .jsf extension being in the url, since applications could use anything for their servlet mapping. Tried solving the "yuiComp is undefined" exception, but haven't succeeded so far, so made it just skip over setting the properties for now. This seems to only affect tabSet, sometimes. I'm going to try re-sequencing some of the code so that all the use statements happen before ondomready. But I just wanted to commit everything before trying experiments. I'll also re-examine my theory of mis-matched braces in our tabset javascript code. Found that our CSS files were still referencing yui/2_8_1 which was breaking the tabSet pre-styling and also may have affected the buttons. Here's the list of outstanding issues, in order of importance: tabSetProxy cancelOnInvalid="true" not working Javascript exception yuiComp. Temporarily worked around with return Regex not handling jsessionid and hardcoding .jsf extension Not fine grained 2in3 jar inclusion Subversion 24206
          Hide
          Arturo Zambrano added a comment -
          • fixed regex issues
          • modified build script to only include the necessary resources

          The JS error in the animation page of the showcase in IE, mentioned above doesn't seem to occur any more.
          All calls to YAHOO.log() are already commented out.
          There doesn't seem to be any issues with skinning.

          Show
          Arturo Zambrano added a comment - fixed regex issues modified build script to only include the necessary resources The JS error in the animation page of the showcase in IE, mentioned above doesn't seem to occur any more. All calls to YAHOO.log() are already commented out. There doesn't seem to be any issues with skinning.
          Hide
          Ken Fyten added a comment -

          I've noticed that with these changes the dateTimeEntry component in none-popup mode now flashes (slowly) whenever a date is selected in ace-showcase. Seems like it's re-initializing and redrawing but not sure if it's due to none-optimal page structure.

          Show
          Ken Fyten added a comment - I've noticed that with these changes the dateTimeEntry component in none-popup mode now flashes (slowly) whenever a date is selected in ace-showcase. Seems like it's re-initializing and redrawing but not sure if it's due to none-optimal page structure.
          Hide
          Arturo Zambrano added a comment -

          Yes I had noted that behaviour before. About a week ago I commented on it. It might be because of creating a new YUI instance of each selection event or update. I had tried to cache a single YUI instance to re-use in these cases, but for some reason it didn't work. I'll try something similar.

          Show
          Arturo Zambrano added a comment - Yes I had noted that behaviour before. About a week ago I commented on it. It might be because of creating a new YUI instance of each selection event or update. I had tried to cache a single YUI instance to re-use in these cases, but for some reason it didn't work. I'll try something similar.
          Hide
          Mark Collette added a comment -

          The tabSetProxy cancelOnInvalid="true" not working has been spun off into ICE-6680

          The regex not handling jsessionid and hardcoding .jsf extension has been fixed, and the follow-up IE issue was resolved in ICE-6682.

          The not fine grained 2in3 jar inclusion issue was fixed, and the follow-up issue with dateTimeEntry was resolved in ICE-6688.

          The Javascript exception yuiComp issue has been temporarily worked-around in the code, but is still outstanding.

          Show
          Mark Collette added a comment - The tabSetProxy cancelOnInvalid="true" not working has been spun off into ICE-6680 The regex not handling jsessionid and hardcoding .jsf extension has been fixed, and the follow-up IE issue was resolved in ICE-6682. The not fine grained 2in3 jar inclusion issue was fixed, and the follow-up issue with dateTimeEntry was resolved in ICE-6688. The Javascript exception yuiComp issue has been temporarily worked-around in the code, but is still outstanding.
          Hide
          Mark Collette added a comment -

          The component loading times have increased, so I'm committing my change that sequences the YUI.use statements to come before the domready callback, which seems to help.

          Subversion 24230

          Show
          Mark Collette added a comment - The component loading times have increased, so I'm committing my change that sequences the YUI.use statements to come before the domready callback, which seems to help. Subversion 24230
          Hide
          Mark Collette added a comment -

          Profiling of the loading within IE 8 indicates that we should explore coalescing our use() statements, as it appears to be recalculating dependencies each time we call it, which takes noticeable time.

          Show
          Mark Collette added a comment - Profiling of the loading within IE 8 indicates that we should explore coalescing our use() statements, as it appears to be recalculating dependencies each time we call it, which takes noticeable time.
          Hide
          Ken Fyten added a comment -

          The initial integration work is complete. Any concerns with possible optimizations within the components should be spun off as separate JIRAs.

          Show
          Ken Fyten added a comment - The initial integration work is complete. Any concerns with possible optimizations within the components should be spun off as separate JIRAs.

            People

            • Assignee:
              Arturo Zambrano
              Reporter:
              Ken Fyten
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: