2

I'm using an external scroll plugin viz. mCustomScrollbar (GIT Hub) to add scroll functionality dynamically to div.

Since I am unable to use ui:scrollerWrapper, newly added Lightning component in the Winter '17 for adding scroll functionality dynamically, I'm depending upon external scroll plugin.

mCustomScrollbar works fine when Locker Service is deactivated. But when Locker Service is active, it throws following error:

Uncaught rerender threw an error in 'markup://aravindajith:Test' [Object.defineProperty called on non-object]

Code to replicate the issue:-

Component:-

<aura:component description="testComp" implements="force:appHostable,flexipage:availableForAllPageTypes">
    <ltng:require styles="{!$Resource.aravindajith__staticResource + '/scriptsTest/jquery.mCustomScrollbar.css'}"/>
    <ltng:require scripts="{!join(',',
          $Resource.namespace__staticResource + '/scriptsTest/jquery-2.2.4.js',                    
          $Resource.namespace__staticResource + '/scriptsTest/jquery.mousewheel.js',
          $Resource.namespace__staticResource + '/scriptsTest/jquery.mCustomScrollbar.js'                           
                )}"
              afterScriptsLoaded="{!c.scriptsLoaded}" />
    <aura:attribute name="isResourcesLoaded" type="Boolean" default="false"/>
        <div class="mainWrap">
            <div class="testDiv">        
                Lightning includes the Lightning Component Framework and some exciting tools for developers. Lightning makes it easier to build
responsive applications for any device.
Lightning includes these technologies:
Lightning components give you a client-server framework that accelerates development, as well as app performance, and is ideal
for use with the Salesforce1 mobile app and Salesforce Lightning Experience.
The Lightning App Builder empowers you to build apps visually, without code, quicker than ever before using off-the-shelf and
custom-built Lightning components. You can make your Lightning components available in the Lightning App Builder so administrators
can build custom user interfaces without code.
Using these technologies, you can seamlessly customize and easily deploy new apps to mobile devices running Salesforce1. In fact, the
Salesforce1 mobile app and Salesforce Lightning Experience are built with Lightning components.
This guide provides you with an in-depth resource to help you create your own standalone Lightning apps, as well as custom Lightning
components that can be used in the Salesforce1 mobile app. You will also learn how to package applications and components and
distribute them in the AppExchange.                   

        </div>
    </div>            
</aura:component>

Static Resources Used:-

jquery.mCustomScrollbar.css

jQuery version - 2.2.4

jquery.mousewheel.js

jquery.mCustomScrollbar.js

Controller:-

({
    scriptsLoaded : function(component, event, helper){
        component.set("v.isResourcesLoaded",true);
    }        
})

Helper:-

({
    addScroll : function(component) {
        if(component.isValid() && component.get("v.isResourcesLoaded")){
            $('.mainWrap').mCustomScrollbar({
                setTop: 0,
                axis: 'xy',
                contentTouchScroll: 25,
                advanced: {autoExpandHorizontalScroll:true},                    
             }); 
        }
   }
})

Renderer:-

({
    afterRender: function(component, helper) {
        this.superAfterRender();                    
    },
    rerender: function(component, helper) {
        this.superRerender();   
        helper.addScroll(component);
    }   
})

CSS:-

.THIS.mainWrap{
    height:300px;
    max-width:400px;   
}
.THIS .testDiv{
    width:600px;    
}

Screenshot when Locker Service is active:-

Error shown when LS is active

Screenshot when Locker Service is not active:-

Scroll functionality when LS is off

3

Have you opened a support case on this so we can track getting this fixed? Your scenario does look like it should work under Locker - although there is quite a bit of code under the surface of those libraries - as long as they do not violate the DOM visibility rules this should work.

With that said I am skeptical that this works inside of one.app (irregardless of Locker) LC tabs, pages etc because of long standing issues with the app architecture not exposing enough control for you to disable its default scrolling. Have you tested this inside an LC tab with Locker deactivated?

  • Hi @DougChasman, Thanks a lot for looking into this. No, we currently do not have any support case open regarding this. Yes Doug, I've tested this inside LC tab with Locker deactivated and custom scroll is working fine (even inside Salesforce1 app). Can you please tell me if there are any workarounds to add scroll dynamically to a div? Is there any way we can use slds-scrollable in Salesforce1 app? – SE_User Nov 4 '16 at 11:36
  • If it's working in all of the locations you need it to with Locker deactivated and as long as the library is CSP and strict mode compliant I'd like to see about getting it working as is under Locker instead of changing anything on your end. Please open a case and post the case ID here so I can follow up on it and keep our support team in the loop. – Doug Chasman Nov 4 '16 at 12:08
  • @DougChasman - The support case number is 14893454. – PKMAN Nov 8 '16 at 0:25
0

Interacted about this on "Lightning Components - Trailblazers" group. Cross posting here,

Problem is that mCustomScroll uses window.top property, which is not supported by Locker Service (see http://documentation.auraframework.org/lockerApiTest/secureWindow.app?aura.mode=DEV ). You could work around this by explicitly assigning "top" a value (e.g. window.top = window)

The exception which I encountered was at _canAccessIFrame method inside Jquery.mCustomScrollbar_V1:

_canAccessIFrame=function(iframe){
var html=null;
if(!iframe){
try{
var doc=top.document;
html=doc.body.innerHTML;
}catch(err){/* do nothing */}
return(html!==null);
}

To be sure, try setting window.top as early as possible. For example, one approach could be to do it via init event handler. I suppose (not too familiar with the library), the library does this to take care of some nested iframes usecase, so as long as you are doing that setting top to the window itself should be ok for you.

How did I debug: Enabled debug mode from setup, and loaded the repro component provided (by wrapping it in a simple app vs going through the builder for simplicity) with Chrome Dev toolbar open and "pause on exceptions" setting turned on.

Note: We are planning to log a story around re-evaluating support for window.top in a future release in locker service. Current design prevents access to it.

  • Thanks for looking into this @esalman. Oh, ok. Then can you please tell me if default scroll would work anytime soon in Salesforce1 app (With the functionality to add scroll dynamically too)? Also, it would be very helpful if you could suggest any other scroll lugin or other workaround to enable scroll functionality. – SE_User Dec 12 '16 at 8:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.