Andrei Nikolaev
Andrei Nikolaev

Reputation: 113

redeclare javascript function

I hope that somebody can help me. I want to redeclare js function by extension. For example, there is the basic js function on website:

function foo(){
..something here..
}

i want to redeclare it by own function with the same name. how it will be easiest to do?

edit 1. i'll try to explain better.

there is a native code in website:

Notifier = {
  debug: false,
  init: function (options) {
    curNotifier = extend({
      q_events: [],
      q_shown: [],
      q_closed: [],
      q_max: 3,
      q_idle_max: 5,
      done_events: {},
      addQueues: curNotifier.addQueues || {},
      recvClbks: curNotifier.recvClbks || {},
      error_timeout: 1,
      sound: new Sound('mp3/bb1'),
      sound_im: new Sound('mp3/bb2')
    }, options);

    if (!this.initFrameTransport() && !this.initFlashTransport(options)) {
      return false;
    }
    this.initIdleMan();

    if (!(curNotifier.cont = ge('notifiers_wrap'))) {
      bodyNode.insertBefore(curNotifier.cont = ce('div', {id: 'notifiers_wrap', className: 'fixed'}), ge('page_wrap'));
    }
  },
  destroy: function () {
    Notifier.hideAllEvents();
    curNotifier.idle_manager.stop();
    curNotifier = {};
    re('notifiers_wrap');
    re('queue_transport_wrap');
  },
  reinit: function () {
    ajax.post('notifier.php?act=a_get_params', {}, {
      onDone: function (options) {
        if (options) {
          curNotifier.error_timeout = 1;
          this.init(options);
        } else {
          curNotifier.error_timeout = curNotifier.error_timeout || 1;
          setTimeout(this.reinit.bind(this), curNotifier.error_timeout * 1000);
          if (curNotifier.error_timeout < 256) {
            curNotifier.error_timeout *= 2;
          }
        }
      }.bind(this),
      onFail: function () {
        curNotifier.error_timeout = curNotifier.error_timeout || 1;
        setTimeout(this.reinit.bind(this), curNotifier.error_timeout * 1000);
        if (curNotifier.error_timeout < 256) {
          curNotifier.error_timeout *= 2;
        }
        return true;
      }.bind(this)
    });
  }
}

and function Sound

function Sound(filename) {
  var audioObjSupport = false, audioTagSupport = false, self = this, ext;
  if (!filename) throw 'Undefined filename';

  try {
    var audioObj = ce('audio');
    audioObjSupport = !!(audioObj.canPlayType);

    if (('no' != audioObj.canPlayType('audio/mpeg')) && ('' != audioObj.canPlayType('audio/mpeg')))
      ext = '.mp3?1';
    else if (('no' != audioObj.canPlayType('audio/ogg; codecs="vorbis"')) && ('' != audioObj.canPlayType('audio/ogg; codecs="vorbis"')))
      ext = '.ogg?1';
    else
      audioObjSupport = false;
  } catch (e) {}
  // audioObjSupport = false;

  if (audioObjSupport) {
    audioObj.src = filename + ext;
    var ended = false;
    audioObj.addEventListener('ended', function(){ended = true;}, true);
    audioObj.load();
    this.playSound = function() {
      if (ended) {
        audioObj.load();
      }
      audioObj.play();
      ended = false;
    };
    this.pauseSound = function() {
      audioObj.pause();
    };
  } else {
    cur.__sound_guid = cur.__sound_guid || 0;
    var wrap = ge('flash_sounds_wrap') || utilsNode.appendChild(ce('span', {id: 'flash_sounds_wrap'})),
        guid = 'flash_sound_' + (cur.__sound_guid++);

    var opts = {
      url: '/swf/audio_lite.swf?4',
      id: guid
    }
    var params = {
      swliveconnect: 'true',
      allowscriptaccess: 'always',
      wmode: 'opaque'
    }
    if (renderFlash(wrap, opts, params, {})) {
      var swfObj = browser.msie ? window[guid] : document[guid],
          inited = false,
          checkLoadInt = setInterval(function () {
        if (swfObj && swfObj.paused) {
          try {
            swfObj.setVolume(1);
            swfObj.loadAudio(filename + ext);
            swfObj.pauseAudio();
          } catch (e) {debugLog(e);}
        }
        inited = true;
        clearInterval(checkLoadInt);
      }, 300);
      self.playSound = function() {
        if (!inited) return;
        swfObj.playAudio(0);
      };
      self.pauseSound = function() {
        if (!inited) return;
        swfObj.pauseAudio();
      };
    }
  }
}
Sound.prototype = {
  play: function() {
    try {this.playSound();} catch(e){}
  },
  pause: function() {
    try {this.pauseSound();} catch(e){}
  }
};

when i try to add injection with redeclaration function Sound it doesn't work. if i create my own function, for example, xSound and сall it this way:

cur.sound = new xSound('mp3/bb1');

it's working.

Upvotes: 2

Views: 6356

Answers (3)

rsanchez
rsanchez

Reputation: 14657

Remember that an extension's Content Script code and the webpage code run in different execution contexts.

So if you want to redefine a function that exists in the webpage context, you'll have to inject your code into the webpage. Take a look at this answer by Rob W for different methods of doing that: Insert code into the page context using a content script

Upvotes: 0

zpavlinovic
zpavlinovic

Reputation: 1547

You can do it like this, for example:

foo = function(args) {
    // method body...
}

JavaScript is a programming language where functions are first-class citizens so you can manipulate them like other types.

UPDATE:

Make sure that this piece of code actually does the redefinition and not the first definition. (thanks to @jmort253)

Upvotes: 9

I Hate Lazy
I Hate Lazy

Reputation: 48761

function foo(){
   // ..something else here..
}

Upvotes: 2

Related Questions