0

I have an uncommon problem.

I don't have access to the head or the database for the company's Drupal website, however, I'm building a "plugin" for the site using the provided "JS Injector".

I hack away locally and just copy/paste my javascript right into the injector (I can't think of a worse development environment now that I think of it, product development takes forever).

In my haste, I accidentally put in my call to jQuery that I need locally. This killed the page, mostly, because calling jQuery twice is bad. The page paint/CSS renders but I can't access any of the management modules to edit the node I updated so I can fix the issue.

Since the "Customize This Page" make an ajax call to initialize any of the Drupal backend UI stuff. My idea is to access the JS Injector from another internal page that I've setup and run a script that could somehow "reach in" and remove my call to jQuery before it gets rendered.

I it possible to grab a script by it's source? I can't use jQuery to remove a second jQuery script on the page...can I? That hurts just asking.

Here is the exact script I'm trying to remove, there is no type attribute. Just a src:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>


function getScript()
{
  var s;
  s = document.getElementsByTagName('script');

  if(s.querySelector('[src]') === "https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"){
      this.remove;
  }
}
removeScript();

is something like this possible?

td;dr removing a call to jquery before jquery loads.

SOLUTION (thanks to Serge Seredenko):

// ==UserScript==
// @name        test script
// @namespace   test
// @include     http://your.website.com/
// @version     1
// @grant       unsafeWindow
// @run-at      document-start
// ==/UserScript==

unsafeWindow.watch('jQuery', function(i, o, n) {
  n.noConflict()
  if (unsafeWindow.__old_jQuery)
    return unsafeWindow.__old_jQuery
  unsafeWindow.__old_jQuery = n
  return n
})
bill m
  • 111
  • 2
  • 13
  • Do I understand your problem correctly: you broke a page, and that page is your only way to edit itself? – Serge Seredenko Aug 30 '15 at 16:43
  • Yes. However, I have access to the javascript on the page from another internal page on the site. I'm sort of at a loss. This is my last attempt to try and fix it before sending a ticket over to the dev team that manages the backend of the site. – bill m Aug 30 '15 at 18:45
  • Curious why I was down-voted. – bill m Aug 30 '15 at 18:46
  • Is that another internal page also corrupted? If not, why can't you make required edit? – Serge Seredenko Aug 30 '15 at 18:47
  • The other internal page is not corrupt; jQuery still works on that page. The reason i can't edit the page is because the UI elements on the page get rendered after an ajax call. Since I broke jQuery on that page the call doesn't get sent, therefore, I can't get to the "Edit this Block" section. So my idea was to add a site-wide script on that other page that would remove my second call to jQuery that I had inserted on the home page by accident. I can target the homepage from another internal page. – bill m Aug 30 '15 at 18:49
  • I still cannot fully understand what happened. Is it so that a page allows editing its html, and you inserted ` – Serge Seredenko Aug 30 '15 at 18:54
  • Yes. I have some html, css, js running inside an HTML editor. As I build out my little app thing locally I just copy/paste my code it into the site's HTML editor. This time I forgot to omit the thereby killing that page's jQuery because I called it twice. If jQuery can't run then I can't access that HTML editor. Ultimately killing my ability to fix my mistake. – bill m Aug 30 '15 at 18:58
  • Here is the "Customize Button" http://take.ms/eDcZn. Clicking that runs an AJAX call that pulls up this: http://take.ms/kChDZ. Here is the TinyCME type thing I can put my code: http://take.ms/tfGoT. This is how we prototype new plugins and features for our sites. – bill m Aug 30 '15 at 19:01
  • Including jquery twice doesn't do anything bad for me. Are you sure that's the problem? What does the console say? – Serge Seredenko Aug 30 '15 at 19:12
  • Uncaught TypeError: $(...).once is not a function – bill m Aug 30 '15 at 19:16
  • I'm pretty sure that's the issue because I think there are two different version of jQuery running on the page now. Nothing happened until I accidentally added the second call to jquery. – bill m Aug 30 '15 at 19:17
  • For the record, in my javascript I have to use jQuery instead of $ to reference jQuery. – bill m Aug 30 '15 at 19:21

1 Answers1

1

Ok, here's what you could try. Install firefox, then Greasemonkey extension, which will allow you to inject js into pages by browser. Greasemonkey scripts allow @run-at document-start directive (read manuals), which means that they are gonna run before html is loaded. Now, you have to think of some way to do some magic with jQuery. I personally tried this, and it works:

// ==UserScript==
// @name        test
// @namespace   test
// @include     http://manage/arena/*
// @version     1
// @grant       none
// @run-at      document-start
// ==/UserScript==

unsafeWindow.watch('jQuery', function(i, o, n) {
  n.noConflict()
  if (unsafeWindow.__old_jQuery)
    return unsafeWindow.__old_jQuery
  unsafeWindow.__old_jQuery = n
  return n
})

As you see, what I do here is capture first loaded jQuery object and save it. In case something tries to reassign window.jQuery property (for example, new <script> tag), script catches that and returns old value.
I also included noConflict call every time new jQuery is built. I don't know if you need that (look up source code of your website to know if it does .noCoflict()), maybe you will have to do stuff with window.$ instead of window.jQuery; maybe both. Anyway, I believe you get the idea. Hope it helps. Don't forget to man window.watch, works in firefox.

Serge Seredenko
  • 3,541
  • 7
  • 21
  • 38
  • Downloaded Greasemonkey, created a new snippet and added yours. Ran it and got this error: http://take.ms/QxnyZ. unsafeWindow is not defined. – bill m Aug 30 '15 at 21:34
  • @billm is it firefox? Try replacing `@grant none` with `@grant unsafeWindow` – Serge Seredenko Aug 30 '15 at 21:38
  • I tried in both FF and Chrome. It worked in FF! Although, it completely killed jQuery on the page and won't let it run at all. I guess I just need it to run once. I'm thinking I need try modifying the script to catch one instance of jquery. – bill m Aug 30 '15 at 21:59
  • It does catch. Write `jQuery.ajax()` in console to see that jq is actually present. Is it? – Serge Seredenko Aug 30 '15 at 22:03
  • @billm Please use the script exactly as I provided in answer (except `@include http://manage/arena/*` changed to your site) and tell me what happens after jQuery.ajax() call from console. Also, what version of firefox and greasemonkey do you use? – Serge Seredenko Aug 30 '15 at 22:25
  • Oh my god it worked! You just made me so happy. I was able to access the modules I needed. I also learned about a new tool, Greasemonkey. Thanks again, mate. – bill m Aug 31 '15 at 00:53
  • @billm You're welcome! You may provide info here in comments about what you had to fix in the script from the answer, for others to find. – Serge Seredenko Aug 31 '15 at 01:06
  • Updated with what worked for me in Firefox. thanks again. – bill m Sep 01 '15 at 04:18