Magento: Remove JS Files Added by Extension Programmatically

headjavascripttheme

I have a 3rd party extension adding JS in via an observer:

<?php
class Anowave_Owl_Model_Observer extends Mage_Core_Model_Abstract
{
    public function dispatch(Varien_Event_Observer $observer)
    {
        if (Mage::app()->getLayout()->getBlock('owl') && Mage::app()->getLayout()->getBlock('owl')->getSlider())
        {
            $format = Mage::app()->getLayout()->getBlock('owl')->getFormat();

            if ($format instanceof Anowave_Owl_Block_Format)
            {
                $format->addCss()->addJs();
            }
        }

        return $this;
    }
}

Where addJs is defined in a block class as:

public function addJs()
{
    $script = 'js/jquery-1.11.0.min.js';
    Mage::app()->getLayout()->getBlock('head')->addItem('skin_js', $script);
 }

Rather than hack the module, I'm trying to remove the loaded jquery via removeItem i.e.

   <default>
     <reference name="head">
        <action method="removeItem">
            <type>skin_js</type>
            <name>js/jquery-1.11.0.min.js</name>
        </action>
    </reference>
   </default>  

In local.xml. But it does not work.
I know that my syntax and pathing are correct because I can unload/remove other JS files this way in the same folder (ones which are specified by their extension's layout XML instead).
I thought local.xml was processed after all other layout registration steps, but I guess not (?)
So I don't think removeItem in layout is an option.
I'd be willing to use

        Mage::app()->getLayout()->getBlock('head')->removeItem('skin_js', $script);

In a custom module, but how would i know that all the previous addJS() processing has finished executing?

Any ideas or solutions appreciated!

Best Answer

I don't know what event is observed in the original extension by Anowave_Owl_Model_Observer::dispatch but I assume is some event dispatched after the layout is loaded and before it is rendered.
That's why you cannot remove via layout files the file added via observer.
But that's not important.
You can use the same event in one of your modules, you just have to make sure your observer is executed after the one in the extension.
This can be achieved simply by making your extension depend on the original one.

So you need something like this:

app/etc/modules/[Namespace]_[Module].xml - the declaration file

<?xml version="1.0"?>
<config>
    <modules>
        <[Namespace]_[Module]>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Anowave_Owl />
            </depends>
        </[Namespace]_[Module]>
    </modules>
</config>

app/code/local/[Namespace]/[Module]/etc/config.xml - the configuration file

<?xml version="1.0"?>
<config>
    ....
    <frontend><!-- or global depending on observed from the original extension -->
        <events>
            <event_name_goes_here>
                <observers>
                     <[namespace]_[module]>
                          <class>[module]/observer</class>
                          <method>removeScripts</method>
                     </[namespace]_[module]>
                </observers>
            </event_name_goes_here>
        </events>
    </frontend><!-- or global -->
</config>

app/code/local/[Namespace]/[Module]/Model/Observer.php - the observer

<?php
class [Namespace]_[Module]_Model_Observer
{
    public function removeScripts()
    {
        ....
        Mage::app()->getLayout()->getBlock('head')->removeItem('skin_js', $script);
    }
}
Related Topic