Discussion for the unofficial, community-developed addons, extensions and scripts built for the Waze Map Editor.

The official index of these tools is the Community Plugins, Extensions and Tools wiki page.

Post Reply
Forum rules
Discussion for the unofficial, community-developed addons, extensions and scripts built for the Waze Map Editor.

DO NOT START a new thread unless it is about a new idea. Keep discussion of existing tools within the main thread for that tool.

The official index of these tools is the Community Plugins, Extensions and Tools wiki page.

Script authors: support recovering from Event Mode

Post by Glodenox
Very recently the event mode has become available in the WME (might be restricted to some countries, not entirely sure). When this mode gets activated, tab(s) generated by your userscript will be removed because everything in div#sidebarContent will be cleared and replaced with the sidebar content for the event mode.

So whenever the mode is changed, you'll need to re-add your tab. The cleanest solution I could find for this is adding an event listener on the modeController, like so:

Code: Select all

// This assumes you have a function named init() that you want to call
Waze.app.modeController.model.bind('change:mode', init);
I'd suggest to just store the div in which your tab stores its data in a variable and add that div again as a tab whenever the mode is changed back.

If you wish to know which mode has become active (as your script is probably not useful within Event mode), you can check the second parameter that the event call gives (see below). Default mode = 0, Event mode = 1
The callback function for a mode change has this signature:

Code: Select all

function(model, modeId, context?)
Glodenox
Waze Global Champs
Waze Global Champs
Posts: 1568
Answers: 1
Answers: 1
Has thanked: 278 times
Been thanked: 946 times

POSTER_ID:17118915

1

Send a message
Last edited by Glodenox on Thu Aug 17, 2017 6:34 am, edited 1 time in total.
Belgium & Luxembourg Coordinator • Script Writing Community Coordinator
https://www.tomputtemans.com/images/WazeBelgium.pnghttps://www.tomputtemans.com/images/WazeWMEbeta.png

Post by Glodenox
Here's a simplified version of what I do in one of my userscripts.

Code: Select all

// ==UserScript==
// ...
// ==/UserScript==
(function() {
  function init(e) {
    if (e && e.user == null) {
      return;
    }
    if (typeof Waze === 'undefined' || typeof Waze.map === 'undefined') {
      setTimeout(init, 800);
      log('Waze object unavailable, map still loading');
      return;
    }
    if (document.getElementById('user-info') == null) {
      setTimeout(init, 500);
      log('user-info element not yet available, map still loading');
      return;
    }
    if (typeof Waze.loginManager === 'undefined') {
      setTimeout(init, 300);
      return;
    }
    if (!Waze.loginManager.hasUser()) {
      Waze.loginManager.events.register("login", null, init);
      Waze.loginManager.events.register("loginStatus", null, init);
      return;
    }
    var tab = setupTab();
    if (Waze.app.modeController) {
      Waze.app.modeController.model.bind('change:mode', function(model, modeId) {
        if (modeId == 0) {
          setupTab(tab);
        }
      });
    }
    // fill tab with other elements
  }
  
  // Create a tab for the userscript and possibly receive a previous tab to restore (usually in case of a mode change)
  function setupTab(recoveredTab) {
    var userInfo = document.getElementById('user-info'),
      tabHandles = userInfo.querySelector('.nav-tabs'),
      tabs = userInfo.querySelector('.tab-content'),
      tabHandle = document.createElement('li'),
      tab = document.createElement('div');
    tabHandle.innerHTML = '<a href="#sidepanel-youruserscript" data-toggle="tab" title="youruserscript">youruserscript</a>';
    if (recoveredTab) {
      tab = recoveredTab;
    } else {
      tab.id = 'sidepanel-youruserscript';
      tab.className = 'tab-pane';
    }
    tabHandles.appendChild(tabHandle);
    tabs.appendChild(tab);
    return tab;
  }

  init();
})();
Glodenox
Waze Global Champs
Waze Global Champs
Posts: 1568
Answers: 1
Has thanked: 278 times
Been thanked: 946 times
Send a message
Belgium & Luxembourg Coordinator • Script Writing Community Coordinator
https://www.tomputtemans.com/images/WazeBelgium.pnghttps://www.tomputtemans.com/images/WazeWMEbeta.png

Post by Glodenox
Hmm, can't say I've seen that happen before. Do you have a check in your initialisation function for Waze.app?

Code: Select all

    if (typeof Waze.app === 'undefined') {
      setTimeout(init, 300); // replace init with the actual name of your initialisation function
      return;
    }
Glodenox
Waze Global Champs
Waze Global Champs
Posts: 1568
Answers: 1
Has thanked: 278 times
Been thanked: 946 times
Send a message
Belgium & Luxembourg Coordinator • Script Writing Community Coordinator
https://www.tomputtemans.com/images/WazeBelgium.pnghttps://www.tomputtemans.com/images/WazeWMEbeta.png

Post by Glodenox
FYI, I only just now noticed that changing to events mode also resets the layers drawer. If you've added a layer in that menu, you'll need to add it again whenever the editor mode changes.
Glodenox
Waze Global Champs
Waze Global Champs
Posts: 1568
Answers: 1
Has thanked: 278 times
Been thanked: 946 times
Send a message
Belgium & Luxembourg Coordinator • Script Writing Community Coordinator
https://www.tomputtemans.com/images/WazeBelgium.pnghttps://www.tomputtemans.com/images/WazeWMEbeta.png

Post by iainhouse
The advice in the post above has been invaluable, but I freely admit I didn't understand it all at first. However, my script now happily re-creates it's own tab when exiting event mode.

I've noticed that few of the other scripts I use have yet been updated to do so. So in case it's any help to anyone, I thought I'd share the way I deal with this problem. This code should also initialise scripts successfully in both Chrome and Firefox: my previous versions were failing frequently with Firefox due to relying on a non-existent event.

The code below is a stripped-down version of my WMEFU script with all the stuff specific to WMEFU removed, some more obvious names and plenty of extra comments. As such, I'd be amazed if it actually ran as-is, but it shows the general framework and method I'm using.

Code: Select all

(function() {

// global variables
var myAddonStorageVariable;

function init1() {
	// If the Waze map object doesn't yet exist, then we have to
	//wait for it. This will re-call init1 in 200ms
	if(!window.Waze.map) {
		setTimeout(init1, 200);
		return;
	}
	
	//Do initial setup here, including creating the contents 
	//for the tab and storing it in a global variable
	//
	//
	myAddonStorageVariable = functionToCreateAddon();
	//or create it directly in this function
	//Make sure this HTML object has an id!
	//
	// call function to add the tab. Tell it we're in normal editor 
	// mode (second parameter=0), since we're loading WME now
	addMyTab(null,0);
	//pass control to init2
	init2();
}

function init2() {

	//If my tab doesn't yet exist, then we have to wait again
	if (!document.getElementById('idOfMyAddonHTMLElement')) {
		setTimeout(init2, 200);
		return;
	}
	//My tab should be there now, so we can proceed with the rest
	//of initialisation. Things like reading settings from local
	//storage, setting values, applying settings, setting up event
	//handlers and so on, including:

	// set up event to recreate my tab when MTE mode is exited
	Waze.app.modeController.model.bind('change:mode', addMyTab);

}

function functionToCreateAddon() {
	//create the contents of my side-panel tab
	var addon = document.createElement('section');
	var section = document.createElement('p');
	addon.id = "idOfMyAddonHTMLElement";
	section.innerHTML  = 'This is a useless tab!<br>';
	addon.appendChild(section);
	addon.className = "tab-pane";
	return addon;
}

function addMyTab(model,modeID) {
	//This function will be called during initialisation, but will
	//also need to be called to recreate the tab when exiting MTE mode
	//It is used as a callback function and modeID will identify which
	//editor mode is valid
	if (modeID === 0) {
		//entering editor mode, so recreate tab
		tabsLooper();
	} else {
		//entering MTE mode, so do nothing
		return;
	}
}

function tabsLooper() {
	//This function actually creates the tab
	//If the tab framework doesn't yet exist, it will try again in 200ms
	var userTabs = getId('user-info');
	var navTabs = getElementsByClassName('nav-tabs', userTabs)[0];
	if (typeof navTabs === "undefined") {
		//the basic tabs aren't there yet, so I can't add mine
		setTimeout(tabsLooper, 200);
	} else{
		var tabContent = getElementsByClassName('tab-content', userTabs)[0];
		newtab = document.createElement('li');
		newtab.innerHTML = '<a href="#idOfMyAddonHTMLElement" data-toggle="tab">TAB TEXT</a>';
		navTabs.appendChild(newtab);
		tabContent.appendChild(myAddonStorageVariable);
	}
}

function getElementsByClassName(classname, node) {
	if(!node) node = document.getElementsByTagName("body")[0];
	var a = [];
	var re = new RegExp('\\b' + classname + '\\b');
	var els = node.getElementsByTagName("*");
	for (var i=0,j=els.length; i<j; i++)
		if (re.test(els[i].className)) a.push(els[i]);
	return a;
}


// Start it running
setTimeout(init1, 200);
})();
I sincerely hope you find this useful. Please point out any of the obviously stupid mistakes that I've probably made. :lol:
iainhouse
EmeritusChamps
EmeritusChamps
Posts: 11143
Answers: 1
Has thanked: 2173 times
Been thanked: 8188 times
Send a message
https://storage.googleapis.com/wazeoped ... c4/AGC.pnghttps://sign.waze.tools/s2000.pnghttps://sign.waze.tools/c6.png
My scripts: WME FixUI WME Presets :ugeek:
I want to go to a commune in Vermont and deal with no unit of time shorter than a season

Post by JustinS83
If you use WazeWrap to create your layer item in the layer list or to create your script tab these things are handled automatically.
JustinS83  
Waze Global Champs
Waze Global Champs
Posts: 1463
Has thanked: 215 times
Been thanked: 2389 times
Send a message

Post by Philistine11
Has anyone seen a problem with

Code: Select all

Waze.app.modeController.model.bind('change:mode', init);
throwing an error of

Code: Select all

Waze.app is undefined
specifically in Firefox?
Philistine11
Country Manager
Country Manager
Posts: 68
Has thanked: 9 times
Been thanked: 57 times
Send a message