WME Place Interface Enhancements

Enhancements to various Place interfaces

当前为 2017-01-09 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         WME Place Interface Enhancements
// @namespace    https://greasyfork.org/users/30701-justins83-waze
// @version      0.3.0
// @description  Enhancements to various Place interfaces
// @include      https://www.waze.com/editor/*
// @include      https://www.waze.com/*/editor/*
// @include      https://beta.waze.com/*
// @exclude      https://www.waze.com/user/editor*
// @author       JustinS83
// @grant        none
// @require      https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
// @license      GPLv3
// ==/UserScript==

(function() {
    'use strict';

    var settings = {};

    // Your code here...
    function bootstrap(tries) {
        tries = tries || 1;

        if (window.W &&
            window.W.map &&
            window.W.model &&
            $) {
            init();
        } else if (tries < 1000) {
            setTimeout(function () {bootstrap(tries++);}, 200);
        }
    }

    bootstrap();

    function init(){
        var $section = $("<div>", {style:"padding:8px 16px", id:"WMEPIESettings"});
        $section.html([
            '<h4><b>WME Place Interface Enhancements</b></h4>',
            '<div class="controls-container" id="divAreaPlaceSizeControls">',
            '<div id="divShowAreaPlaceSize" class="controls-container"><input type="checkbox" id="_cbShowAreaPlaceSize" class="pieSettingsCheckbox" /><label for="_cbShowAreaPlaceSize">Show area Place size</label></div>',
            '<div id="divShowAreaPlaceSizeImperial"class="controls-container" style="padding-left:30px;"><input type="checkbox" id="_cbShowAreaPlaceSizeImperial" class="pieSettingsCheckbox" disabled /><label for ="_cbShowAreaPlaceSizeImperial"> Show imperial </label></div>',
            '<div id="divShowAreaPlaceSizeMetric" class="controls-container" style="padding-left:30px;"><input type="checkbox" id="_cbShowAreaPlaceSizeMetric" class="pieSettingsCheckbox" disabled /><label for ="_cbShowAreaPlaceSizeMetric"> Show metric</label></div>',
            '</div>',
            '<div class="controls-container" id="divShowLockButtonsRPP"><input type="checkbox" id="_cbShowLockButtonsRPP" class="pieSettingsCheckbox" /><label for="_cbShowLockButtonsRPP">Show lock buttons for RPPs</label></div>',
            '<div class="controls-container" id="divPlaceMenuCustomization">',
            '<b>Place Menu Customization</b></br>',
            buildItemOption(1),
            buildItemOption(2),
            buildItemOption(3),
            buildItemOption(4),
            buildItemOption(5),
            buildItemOption(6),
            buildItemOption(7),
            buildItemOption(8),
            buildItemOption(9),
            buildItemOption(10),
            buildItemOption(11),
            '</div>'

        ].join(' '));
        new WazeWrap.Interface.Tab('PIE', $section.html(), init2);
    }

    function buildNewPlaceList(){
        /*<div class="drawing-controls">
        <span class="drawing-control polygon secondary-control" title="Place (area)"></span>
        <span class="drawing-control main-control point" title="Place (point)"></span>
        </div>
        $('#pieItem1')[0].options[$('#pieItem1')[0].selectedIndex].innerHTML //get selected option text
        */
    }

    function init2(){
        //First load settings
        loadSettings();
        //Second set up event handlers
        $('#_cbShowAreaPlaceSize').change(function() {
            if(this.checked) {
                attachPlaceSizeHandlers();
                updatePlaceSizeDisplay();
                $('#_cbShowAreaPlaceSizeImperial')[0].disabled = false;
                $('#_cbShowAreaPlaceSizeMetric')[0].disabled = false;
            }
            else
            {
                removePlaceSizeHandlers();
                $('#AreaSize').remove();
                $('#_cbShowAreaPlaceSizeImperial')[0].disabled = true;
                $('#_cbShowAreaPlaceSizeMetric')[0].disabled = true;
            }
        });

        $('#_cbShowLockButtonsRPP').change(function() {
            if(this.checked) {
                attachRPPLockButtonHandlers();
            }
            else
            {
                $('#RPPOptionPlaceLockButtonsContainer').remove();
                W.selectionManager.events.unregister("selectionchanged", null, addLockButtons);
                W.model.actionManager.events.unregister("afterundoaction",null, addLockButtons);
                W.model.actionManager.events.unregister("afterclearactions",null, addLockButtons);
                W.model.actionManager.events.unregister("afteraction",null, addLockButtons);
            }
        });

        //Third load settings to interface
        setChecked('_cbShowAreaPlaceSize', settings.ShowAreaPlaceSize);
        setChecked('_cbShowAreaPlaceSizeImperial', settings.ShowAreaPlaceSizeImperial);
        setChecked('_cbShowAreaPlaceSizeMetric', settings.ShowAreaPlaceSizeMetric);
        setChecked('_cbShowLockButtonsRPP', settings.ShowLockButtonsRPP);
        if(settings.ShowAreaPlaceSize){
            $('#_cbShowAreaPlaceSizeImperial')[0].disabled = false;
            $('#_cbShowAreaPlaceSizeMetric')[0].disabled = false;
            attachPlaceSizeHandlers();
        }

        if(settings.ShowLockButtonsRPP)
            attachRPPLockButtonHandlers();

        $('.pieSettingsCheckbox').change(function() {
             var settingName = $(this)[0].id.substr(3);
            settings[settingName] = this.checked;
            saveSettings();
        });

        //Whenever a Place item is changed, read the settings and save to localStorage
        $('[id^="pieItem"]').change(function(){
            for(i=0;i<11;i++){
                settings.NewPlacesList[i] = $('#pieItem'+(i+1))[0].value;
            }
            saveSettings();
        });

        //Load settings into Place Customization list options
        for(i=0; i<11;i++)
            $('#pieItem'+(i+1))[0].value = settings.NewPlacesList[i];
    }

    function buildItemOption(itemNumber){
        var $section = $("<div>", {style:"padding:8px 16px", id:"piePlaceCat" + itemNumber});
        $section.html([
            'Item ',
            itemNumber,
            buildItemList(itemNumber),
            '</br>'
            ].join(' '));

        return $section.html();
    }

    function buildItemList(itemNumber){
        /*var yourSelect = document.getElementById( "your-select-id" );
        alert( yourSelect.options[ yourSelect.selectedIndex ].value )*/
        
        var $places = $("<div>");
        $places.html([
            '<select id="pieItem' + itemNumber + '">',
            '<option value="CAR_SERVICES" style="font-weight:bold;">Car Services</option>',
            '<option value="GAS_STATION">Gas Station</option>',
            '<option value="GARAGE_AUTOMOTIVE_SHOP">Garage / Automotive Shop</option>',
            '<option value="CAR_WASH">Car Wash</option>',
            '<option value="CHARGING_STATION">Charging Station</option>',
            '<option value="TRANSPORTATION" style="font-weight:bold;">Transportation</option>',
            '<option value="AIRPORT">Airport</option>',
            '<option value="BUS_STATION">Bus Station</option>',
            '<option value="FERRY_PIER">Ferry / Pier</option>',
            '<option value="SEAPORT_MARINA_HARBOR">Seaport / Marina / Harbor</option>',
            '<option value="SUBWAY_STATION">Subway Station</option>',
            '<option value="TRAIN_STATION">Train Station</option>',
            '<option value="BRIDGE">Bridge</option>',
            '<option value="TUNNEL">Tunnel</option>',
            '<option value="TAXI_STATION">Taxi Station</option>',
            '<option value="JUNCTION_INTERCHANGE">Junction / Interchange</option>',
            '<option value="PROFESSIONAL_AND_PUBLIC" style="font-weight:bold;">Professional and public</option>',
            '<option value="COLLEGE_UNIVERSITY">College / University</option>',
            '<option value="SCHOOL">School</option>',
            '<option value="CONVENTIONS_EVENT_CENTER">Conventions / Event Center</option>',
            '<option value="GOVERNMENT">Government</option>',
            '<option value="LIBRARY">Library</option>',
            '<option value="CITY_HALL">City Hall</option>',
            '<option value="ORGANIZATION_OR_ASSOCIATION">Organization or Association</option>',
            '<option value="COURTHOUSE">Courthouse</option>',
            '<option value="CEMETERY">Cemetery</option>',
            '<option value="FIRE_DEPARTMENT">Fire Department</option>',
            '<option value="POLICE_STATION">Police Station</option>',
            '<option value="MILITARY">Military</option>',
            '<option value="HOSPITAL_MEDICAL_CARE">Hospital / Medical Care</option>',
            '<option value="OFFICES">Offices</option>',
            '<option value="POST_OFFICE">Post Office</option>',
            '<option value="RELIGIOUS_CENTER">Religious Center</option>',
            '<option value="KINDERGARDEN">Kindergarden</option>',
            '<option value="FACTORY_INDUSTRIAL">Factory / Industrial</option>',
            '<option value="EMBASSY_CONSULATE">Embassy / Consulate</option>',
            '<option value="INFORMATION_POINT">Information Point</option>',
            '<option value="EMERGENCY_SHELTER">Emergency Shelter</option>',
            '<option value="SHOPPING_AND_SERVICES" style="font-weight:bold;">Shopping and services</option>',
            '<option value="ARTS_AND_CRAFTS">Arts & Crafts</option>',
            '<option value="BANK_FINANCIAL">Bank / Financial</option>',
            '<option value="SPORTING_GOODS">Sporting Goods</option>',
            '<option value="BOOKSTORE">Bookstore</option>',
            '<option value="PHOTOGRAPHY">Photography</option>',
            '<option value="CAR_DEALERSHIP">Car Dealership</option>',
            '<option value="FASHION_AND_CLOTHING">Fashion and Clothing</option>',
            '<option value="CONVENIENCE_STORE">Convenience Store</option>',
            '<option value="PERSONAL_CARE">Personal Care</option>',
            '<option value="DEPARTMENT_STORE">Department Store</option>',
            '<option value="PHARMACY">Pharmacy</option>',
            '<option value="ELECTRONICS">Electronics</option>',
            '<option value="FLOWERS">Flowers</option>',
            '<option value="FURNITURE_HOME_STORE">Furniture / Home Store</option>',
            '<option value="GIFTS">Gifts</option>',
            '<option value="GYM_FITNESS">Gym / Fitness</option>',
            '<option value="SWIMMING_POOL">Swimming Pool</option>',
            '<option value="HARDWARE_STORE">Hardware Store</option>',
            '<option value="MARKET">Market</option>',
            '<option value="SUPERMARKET_GROCERY">Supermarket / Grocery</option>',
            '<option value="JEWELRY">Jewelry</option>',
            '<option value="LAUNDRY_DRY_CLEAN">Laundry / Dry Clean</option>',
            '<option value="SHOPPING_CENTER">Shopping Center</option>',
            '<option value="MUSIC_STORE">Music Store</option>',
            '<option value="PET_STORE_VETERINARIAN_SERVICES">Pet Store / Veterinarian Services</option>',
            '<option value="TOY_STORE">Toy Store</option>',
            '<option value="TRAVEL_AGENCY">Travel Agency</option>',
            '<option value="ATM">ATM</option>',
            '<option value="CURRENCY_EXCHANGE">Currency Exchange</option>',
            '<option value="CAR_RENTAL">Car Rental</option>',
            '<option value="FOOD_AND_DRINK" style="font-weight:bold;">Food and Drink</option>',
            '<option value="RESTAURANT">Restaurant</option>',
            '<option value="BAKERY">Bakery</option>',
            '<option value="DESSERT">Dessert</option>',
            '<option value="CAFE">Cafe</option>',
            '<option value="FAST_FOOD">Fast Food</option>',
            '<option value="FOOD_COURT">Food Court</option>',
            '<option value="BAR">Bar</option>',
            '<option value="ICE_CREAM">Ice Cream</option>',
            '<option value="CULTURE_AND_ENTERTAINEMENT" style="font-weight:bold;">Culture & Entertainment</option>',
            '<option value="ART_GALLERY">Art Gallery</option>',
            '<option value="CASINO">Casino</option>',
            '<option value="CLUB">Club</option>',
            '<option value="TOURIST_ATTRACTION_HISTORIC_SITE">Tourist Attraction / History Site</option>',
            '<option value="MOVIE_THEATER">Movie Theater</option>',
            '<option value="MUSEUM">Museum</option>',
            '<option value="MUSIC_VENUE">Music Venue</option>',
            '<option value="PERFORMING_ARTS_VENUE">Performing Arts Venue</option>',
            '<option value="GAME_CLUB">Game Club</option>',
            '<option value="STADIUM_ARENA">Stadium / Arena</option>',
            '<option value="THEME_PARK">Theme Park</option>',
            '<option value="ZOO_AQUARIUM">Zoo / Aquarium</option>',
            '<option value="RACING_TRACK">Racing Track</option>',
            '<option value="THEATER">Theater</option>',
            '<option value="OTHER" style="font-weight:bold;">Other</option>',
            '<option value="CONSTRUCTION_SITE">Construction Site</option>',
            '<option value="LODGING" style="font-weight:bold;">Lodging</option>',
            '<option value="HOTEL">Hotel</option>',
            '<option value="HOSTEL">Hostel</option>',
            '<option value="CAMPING_TRAILER_PARK">Camping / Trailer Park</option>',
            '<option value="COTTAGE_CABIN">Cottage / Cabin</option>',
            '<option value="BED_AND_BREAKFAST">Bed & Breakfast</option>',
            '<option value="OUTDOORS" style="font-weight:bold;">Outdoors</option>',
            '<option value="PARK">Park</option>',
            '<option value="PLAYGROUND">Playground</option>',
            '<option value="BEACH">Beach</option>',
            '<option value="SPORTS_COURT">Sports Court</option>',
            '<option value="GOLF_COURSE">Golf Course</option>',
            '<option value="PLAZA">Plaza</option>',
            '<option value="PROMENADE">Promenade</option>',
            '<option value="POOL">Pool</option>',
            '<option value="SCENIC_LOOKOUT_VIEWPOINT">Scenic Lookout / Viewpoint</option>',
            '<option value="SKI_AREA">Ski Area</option>',
            '<option value="NATURAL_FEATURES" style="font-weight:bold;">Natural Features</option>',
            '<option value="ISLAND">Island</option>',
            '<option value="SEA_LAKE_POOL">Sea / Lake / Pool</option>',
            '<option value="RIVER_STREAM">River / Stream</option>',
            '<option value="FOREST_GROVE">Forest / Grove</option>',
            '<option value="FARM">Farm</option>',
            '<option value="CANAL">Canal</option>',
            '<option value="SWAMP_MARSH">Swamp / Marsh</option>',
            '<option value="DAM">Dam</option>',
            '<option value="PARKING_LOT" style="font-weight:bold;">Parking Lot</option>',
            '<option value="RESIDENCE_HOME" style="font-weight:bold;">Residential</option>',
            '</select>'
            ].join(' '));

        return $places.html();
    }

    function attachRPPLockButtonHandlers(){
        $('#RPPOptionPlaceLockButtonsContainer').remove();
        W.selectionManager.events.register("selectionchanged", null, addLockButtons);
        W.model.actionManager.events.register("afterundoaction",null, addLockButtons);
        W.model.actionManager.events.register("afterclearactions",null, addLockButtons);
        W.model.actionManager.events.register("afteraction",null, addLockButtons);
    }

    function attachPlaceSizeHandlers(){
        W.selectionManager.events.register("selectionchanged", null, updatePlaceSizeDisplay);
        W.model.actionManager.events.register("afteraction",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.register("afterundoaction",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.register("afterclearactions",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.register("noActions",null, noActions);
        updatePlaceSizeDisplay();
    }

    function removePlaceSizeHandlers(){
        W.selectionManager.events.unregister("selectionchanged", null, updatePlaceSizeDisplay);
        W.model.actionManager.events.unregister("afteraction",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.unregister("afterundoaction",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.unregister("afterclearactions",null, updatePlaceSizeDisplay);
        W.model.actionManager.events.unregister("noActions",null, noActions);
    }

    function isChecked(checkboxId) {
        return $('#' + checkboxId).is(':checked');
    }

    function setChecked(checkboxId, checked) {
        $('#' + checkboxId).prop('checked', checked);
    }

    function noActions(){
        setTimeout(updatePlaceSizeDisplay, 100 ); //have to put in a delay for when the user uses undo to clear all actions - WME updates on top of my changes otherwise.
    }

    function updatePlaceSizeDisplay(){
        var count = W.selectionManager.selectedItems.length;
        var metersArea = 0;
        var bold = false;
        if(count === 1){
           var venue = W.selectionManager.selectedItems[0];
           var isArea = venue.geometry.toString().match(/^POLYGON/);
           //var isPoint = venue.geometry.toString().match(/^POINT/);

            if(venue.model.type === "venue" && isArea){
                if($('#AreaSize'))
                    $('#AreaSize').remove();
                metersArea = W.selectionManager.selectedItems[0].model.geometry.getGeodesicArea(W.map.getProjectionObject());

                if(metersArea > 0 && isArea){
                    var ftArea = Math.round(metersArea * 10.76391 *100)/100;

                    var list = $('#landmark-edit-general > ul')[0];
                    var newList = document.createElement("UL");
                    newList.id = "AreaSize";

                    var newItem = document.createElement("LI");
                    if(isChecked("_cbShowAreaPlaceSizeMetric")){
                        newItem.innerHTML = "Area: " + metersArea.toFixed(2) + " m<sup>2</sup>";
                        newList.append(newItem);
                    }

                    if(isChecked("_cbShowAreaPlaceSizeImperial")){
                        newItem = document.createElement("LI");
                        newItem.innerHTML = "Area: " + ftArea.toFixed(2) + " ft<sup>2</sup>";
                        newList.append(newItem);
                    }
                    if(metersArea < 500){
                        newItem = document.createElement("LI");
                        newItem.innerHTML = "<span style='color:red; font-weight:bold;'>Places smaller than 500 m<sup>2</sup>/5382 ft<sup>2</sup> will not show in the client</span>";
                        newList.append(newItem);
                    }
                    list.before(newList);

                    $('#AreaSize').addClass("list-unstyled");
                    $('#AreaSize').addClass("additional-attributes");
                }
            }
        }
    }

    function loadSettings() {
        var loadedSettings = $.parseJSON(localStorage.getItem("WMEPIE_Settings"));
        var defaultSettings = {
            ShowAreaPlaceSize: false,
            ShowAreaPlaceSizeImperial: false,
            ShowAreaPlaceSizeMetric: false,
            ShowLockButtonsRPP: true,
            NewPlacesList: W.Config.venues.categories.clone()
        };
        settings = loadedSettings ? loadedSettings : defaultSettings;
        for (var prop in defaultSettings) {
            if (!settings.hasOwnProperty(prop))
                settings[prop] = defaultSettings[prop];
        }

        if(settings.ShowAreaPlaceSizeImperial === false && settings.ShowAreaPlaceSizeMetric === false)
            if(Waze.prefs.attributes.isImperial)
                settings.ShowAreaPlaceSizeImperial = true;
            else
                settings.ShowAreaPlaceSizeMetric = true;
    }

     function saveSettings() {
        if (localStorage) {
            var localsettings = {
                ShowAreaPlaceSize: settings.ShowAreaPlaceSize,
                ShowAreaPlaceSizeImperial: settings.ShowAreaPlaceSizeImperial,
                ShowAreaPlaceSizeMetric: settings.ShowAreaPlaceSizeMetric,
                ShowLockButtonsRPP: settings.ShowLockButtonsRPP,
                NewPlacesList: settings.NewPlacesList
            };

            localStorage.setItem("WMEPIE_Settings", JSON.stringify(localsettings));
        }
    }

    //Using the same display for lock buttons as ClickSaver (with permission from MapoMatic) - thanks MoM!
    function addLockButtons() {
        if(W.selectionManager.selectedItems.length > 0){
            var item = W.selectionManager.selectedItems[0];
            var isRPP = (item.model.type === "venue" && item.model.attributes.residential === true);

            if(isRPP){
                console.log("adding!!!");
                var attr = item.model.attributes;
                var autoRank = attr.rank;
                var manualRank = attr.lockRank;
                var firstManualRank = manualRank;
                var userRank = WazeWrap.User.Rank() - 1;
                var maxAutoRank = autoRank;
                var disabled = false;

                var $div = $('#RPPOptionPlaceLockButtonsContainer');
                $div.remove();
                $div = $('<div>',{id:'RPPOptionPlaceLockButtonsContainer',style:'margin-bottom:5px;'});
                $div.append('<label class="control-label">Lock</label>');
                var btnInfos = [];

                for(var iBtn=0;iBtn<=6;iBtn++){btnInfos.push({r:iBtn,val:iBtn});}
                btnInfos.forEach(function(btnInfo){
                    var selected = (btnInfo.val === manualRank);
                    disabled = userRank < btnInfo.val;
                    if (btnInfo.val !== 6) {
                        $div.append(
                            $('<div>', {
                                class:'btn btn-lh' + (selected ? ' btn-lh-selected':'') + (btnInfo.r < 6 & (userRank < btnInfo.r || disabled) ? ' disabled' : '')
                            })
                            .text(btnInfo.hasOwnProperty('title') ? btnInfo.title : btnInfo.r + 1)
                            .data('val',btnInfo.hasOwnProperty('val') ? btnInfo.val : btnInfo.r + 1)
                            .hover(function() {})
                            .click(function() {
                                if((userRank >= $(this).data('val')) && (btnInfo.r < 6)) {
                                    W.model.actionManager.add(new UpdateObject(item.model,{lockRank:($(this).data('val'))}));
                                    addLockButtons();
                                }
                            })
                        );
                    }
                });
                $('#landmark-edit-general > div').after($div);
            }
        }
    }

    function listPlaces(){
        var category = "";
        for(i=0; i<W.Config.venues.categories.length; i++){
            category = W.Config.venues.categories[i];
            console.log(category + " Main");
            var subCategories = W.Config.venues.subcategories[category];
            for(var j=0; j<subCategories.length;j++){
                console.log(subCategories[j]);
            }
        }
    }
})();