您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
MyDealz Enstyler enhanced features incl. Amazon Mobile Redirect
当前为
- // ==UserScript==
- // @name EnstylerJS
- // @namespace Enstyler
- // @description MyDealz Enstyler enhanced features incl. Amazon Mobile Redirect
- // @include https://www.preisjaeger.at/*
- // @include https://www.mydealz.de/*
- // @include https://userstyles.org/styles/128262/*
- // @include https://www.amazon.*/gp/aw/*
- // @version 2.12.052
- // @grant GM_getValue
- // @grant GM_setValue
- // @require http://code.jquery.com/jquery-3.1.1.min.js
- // @require http://cdnjs.cloudflare.com/ajax/libs/jquery-throttle-debounce/1.1/jquery.ba-throttle-debounce.min.js
- // @require http://openuserjs.org/src/libs/sizzle/GM_config.js
- // ==/UserScript==
- // ========== INIT EnstylerJS =====================================
- // init Enstyler environment
- var enUserLogin = false;
- var enUserName = '';
- var enSection = '';
- var EnstylerStartTime=Date.now();
- // Parse location for later use
- var enLocParser= location;
- var DEBUG=false;
- // add actions to tread overview @ some places ==================================
- // code used for MyDealz Dealz actions, thanks to mydealz :-)
- var myOuterHtml = [ '<span class="js-options bg--em bRad--a space--h-3 space--v-3 space--mt-3 text--b">', '</span>'];
- var enDealAction = [ '<a title="Sag was dazu" class="link ico ico--pos-l ico--type-comment-blue space--mr-3"'+ // comment 0+1+3
- 'href="<ENSTYLER-HREF-HERE>#comment-form" data-handler="track" data-track="{"action":"scroll_to_comment_add_form","label":"engagement"}">',
- 'Sag was dazu', '', '</a>',
- '<a title="Von Liste entfernen" class="link text--color-blue ico ico--type-bookmark-blue ico--pos-l space--mr-3"' + //un-bookmark 4+5+7
- 'data-handler="track replace" data-replace="{"endpoint":"https:\/\/www.mydealz.de\/threads\/<ENSTYLER-THREADID-HERE>/remove","method":"post"}" data-track="{"action":"save_thread","label":"engagement"}">',
- 'Von Liste entfernen', '', '</a>',
- '<a title="Bearbeiten" class="link text--color-blue ico ico--type-pencil-blue ico--pos-l space--mr-3"'+ // edit 8+9+11
- 'href="<ENSTYLER-HREF-HERE>/edit" data-handler="track" data-track="{"action":"goto_thread_edit_form","beacon":true}">',
- 'Bearbeiten', '', '</a>',
- '<a title="Abgelaufen?" class="thread-expire link ico ico--type-clock-blue ico--pos-l space--mr-3"'+ // expiried not working :-(
- 'href="<ENSTYLER-HREF-HERE>/expire/report" rel="nofollow" data-handler="track replace" data-track="{"action":"report_expired_thread","label":"contribution"}" data-replace="{"endpoint":"https:\/\/www.mydealz.de\/<ENSTYLER-HREF-HERE>/expire\/report"}">',
- 'Abgelaufen?', '', '</a>',
- ];
- var PATTERN = [ /<ENSTYLER-HREF-HERE>/g, // pattern to replace by deal link ...
- /<ENSTYLER-THREADID-HERE>/g // pattern to replace ID
- ];
- var enDealAdd='';
- enDealMarker='thread_'
- function EnstylerDealActions(){
- // use parsed location
- var pathname = enLocParser.pathname;
- var myText=0;
- // no username ??
- if (enUserName != "") {
- pathname = pathname.replace(enUserName + '/',''); // remove username if path is longer
- }
- // display short/no text?
- if ($('.ico--type-grid-subNavActive').length) { myText=1; }
- // default for all Dealz: comment
- enDealAdd = enDealAction[0]+ enDealAction[1+myText] + enDealAction[3];
- // Action for special locations only ===========
- // saved Dealz panel
- if (pathname.endsWith('profile/saved-deals') ){
- // add for user saved-dealz: un-bookmark
- enDealAdd += enDealAction[4]+ enDealAction[5+myText]; + enDealAction[7]
- }
- if (pathname.endsWith('profile/diskussion') || pathname.endsWith(enUserName)){
- // add user dealz and discussions: comment edit
- enDealAdd += enDealAction[8]+ enDealAction[9+myText] + enDealAction[11];
- }
- EnstylerDealActionsDo()
- }
- function EnstylerDealActionsDo() {
- // if logged in and enabled ...
- if (enUserLogin && GM_config.get('enConfMoreDeal')) {
- // every thread on thread page ...
- $('article').each(function () {
- // get ThreadID, Link to Deal and DealID
- var myThread = $(this).attr('id');
- if (!myThread.startsWith(enDealMarker)) {return;}
- var myDealHref = $('#' + myThread + ' .thread-title a').attr('href');
- var myDealID = myThread.replace(enDealMarker,'');
- if (myThread.startsWith('To be')) {return;}
- // compose final HTML
- var newHtml= myOuterHtml[0] + enDealAdd + myOuterHtml[1];
- newHtml = newHtml.replace(PATTERN[0], myDealHref);
- newHtml = newHtml.replace(PATTERN[1], myDealID);
- // append HTML to Deal
- $('#' + myThread +' .thread-infoRow').each(function () {
- $(this).append(newHtml);
- $(this).removeClass('thread-infoRow');
- });
- });
- // actions for somewhere ===========
- // remove unwanted HTML from deal description
- $('.thread--type-detail .userHtml').each(function () {
- // userhtml code from mydalz, need to find jafascript to save automatically :-(
- var myUserhtml = ['<div class="userHtml overflow--wrap-break space--t-3" data-handler="lightbox-xhr" data-lightbox-xhr="{"name":"threads"}">',
- '</div>', // sourround deal description
- ];
- // get inner html
- var myHtml = $(this).html();
- // remove unwanted Stuff: combined <div><br><br> stuff, created by cut'npaste html
- // not elegant, but works ...
- var newHtml = myHtml.replace(/<div>|<div><br>|<\/br>|<\/div>/gi,'');
- newHtml = myHtml.replace(/<p>|<p><br>/gi,'<br><br>');
- newHtml = newHtml.replace(/<br><br><br>|<br><br><br><br>|<br><br><br><br><br>/gi,'<br><br>');
- // replace original with modifyed html
- $(this).replaceWith(myUserhtml[0] + newHtml + myUserhtml[1]);
- });
- } // END enabled
- }
- // show popup user info while click on avatar ... ======================
- function EnstylerAvatarPopup(){
- if (enUserLogin && GM_config.get('enConfUser')) {
- // remove second image from cardview
- addStyleString('.thread-footer-cell a img.avatar.vAlign--all-m.space--mr-1.thread-avatar {display: none;}');
- EnstylerAvatarPopupDo();
- }
- }
- // code used for MyDealz avatar popup, thanks to mydealz :-)
- var enPopupUser = ['<button data-handler="track popover" data-track="{"action":"show_short_user_profile","label":"engagement"}" data-popover="{"endpoint":"',
- '/short","target":"#template-popoverLoader","layout":[{"preset":"e","y":"50%","left":{"offset":0},"width":300,"maxWidth":"100%"}]}">',
- '</button>',
- ];
- function EnstylerAvatarPopupDo() {
- // login needed ... (Error in Popup without login ...)
- // replace every avatar link without popup
- if (enUserLogin && GM_config.get('enConfUser')) {
- $('.thread-footer-cell a.user.linkPlain, .user.linkPlain.thread-user').each(function () {
- // get inner html and link to user profile
- var myHtml = $(this).html();
- var mysrc = $(this).attr('href');
- // seperate user name from image and add class user
- var myAvatar1 = myHtml.replace(/<span.*/,'');
- var myAvatar2 = myHtml.replace(/.*<span class=".* space--mr-1">/,'<span class=" space--mr-1 user link-plain">');
- // show small / medium sized Avatar
- myAvatar1 = myAvatar1.replace('avatar--type-s','avatar--type-m'); //in Dealz
- if (GM_config.get('enConfAvatar')) { myAvatar1 = myAvatar1.replace('thread-avatar','avatar--type-m'); }
- // compose popup
- var myPopup = enPopupUser[0] + mysrc + enPopupUser[1] + myAvatar1 + enPopupUser[2] + '<a href="' + mysrc + '">'+ myAvatar2 + '</a>';
- $(this).replaceWith(myPopup);
- });
- }
- }
- // create select page or scrollwheel for page navigation =============
- var EnstylerPageEnum='enPageEnum';
- var selectList = document.createElement("select");
- selectList.id = EnstylerPageEnum;
- selectList.setAttribute('class', EnstylerPageEnum);
- selectList.onchange = EnstylerPageAction;
- var EnstylerPageEnumDown='enPageEnumDown';
- var selectListDown = document.createElement("select");
- selectListDown.id = EnstylerPageEnumDown;
- selectListDown.onchange = EnstylerPageAction;
- function EnstylerPagePickerCreate() {
- // revome existing picker
- EnstylerPagePickerRemove();
- // if enabled
- if (GM_config.get('enConfPagePicker')) {
- // init values and clear select list
- var page=1;
- var min=1;
- var max=1;
- $(selectList).empty();
- // get page and max from pagenav
- if ( $('.text--color-charcoalTint').length ) {
- // remove linebreaks
- var pageHtml = $('.text--color-charcoalTint').html().replace(/\r?\n|\r/g);
- //locate actual page and last page
- page = pageHtml.replace( /.*>Seite /i ,''); page = page.replace( /<.*/i , '');
- max = pageHtml.replace( /.*page=/ ,''); max = max.replace( /[^0-9].*/i , '');
- if (page == '') {page=1;}
- if (max == '') {max=page;}
- }
- // create page select element
- var x; var last; var option;
- for (x = min; x <= max; ) {
- option = document.createElement("option");
- option.text = x;
- selectList.add(option); //selectListDown.add(option);
- last = x;
- // non linear increment
- var diff = Math.abs(x-page);
- if ( x < 10 || diff < 5) { x++; }
- else if ( x < 1000 && diff > 600) { x += Math.floor(diff/100); }
- else { x += Math.floor(diff/2); }
- }
- // add last page
- if (page > max) { max=page;}
- if (last < max ) {
- option = document.createElement("option");
- option.text = max;
- selectList.add(option); //selectListDown.add(option);
- }
- // set default value
- selectList.value = page; //selectListDown.value = page;
- // Deal Page
- if ($('.voteBar').length) {
- selectList.setAttribute('class', EnstylerPageEnum +' subNavMenu-link subNavMenu-btn voteBar--sticky-off--hide');
- $('.voteBar--sticky-off--hide:last').before(selectList);
- } else {
- // overwiew page
- if (GM_config.get('enConfBtn')) {
- // Place Picker in subnav
- selectList.setAttribute('class', EnstylerPageEnum+' box--all-i subNavMenu-link subNavMenu-btn');
- $('.subNav-label:last').before(selectList);
- } else {
- //place picker in MainNav
- selectList.setAttribute('class', EnstylerPageEnum+' js-navDropDown-messages vAlign--all-m');
- if ($('.test-loginButton').length) {
- $('.test-loginButton').before(selectList);
- } else {
- $('.js-navDropDown-messages').before(selectList);
- }
- }
- }
- }
- }
- function EnstylerPagePickerCreateDo() {
- // get page and max from pagenav
- if ( $('.js-sticky .text--color-charcoalTint').length ) {
- // remove linebreaks
- var pageHtml = $('.js-sticky .text--color-charcoalTint').html().replace(/\r?\n|\r/g);
- //locate actual page and last page
- var page = pageHtml.replace( /.*>Seite /i ,''); page = page.replace( /<.*/i , '');
- if (page == '') {page=1;}
- // set default value
- selectList.value = page; //selectListDown.value = page;
- }
- }
- // goto selected Page
- function EnstylerPageAction() {
- var enPage = 'page=' + $(this).val();
- // remove page= and everthing behind
- var enUrl = enLocParser.toString().replace( /page=.*|#.*/ ,'');
- // add new page parameter
- if ( enUrl.endsWith('?') || enUrl.endsWith('&')) {
- enUrl += enPage;
- } else {
- enUrl += '?'+enPage;
- }
- // add #thread-comments for deal
- if (enSection == '/deals/') { enUrl += '#thread-comments';}
- window.location = enUrl;
- }
- function EnstylerPagePickerRemove() {
- // Removes pagepicker from the document
- $('.'+ EnstylerPageEnum).remove();
- }
- // blacklist do not show dealz containing blacklistet words ==========================
- // search in kategorie, dealtitle, and username
- var enClassHidden = 'enClassHidden';
- var enClassBlackDone = 'enClassBlackDone';
- var enBlacklisted=0;
- var unwantedRegex = [ /[\[\]\(\)\{\}\?\.\:\;\!\"\*\+\ ]/g, // in White/Backlist
- /[\[\]\(\)\{\}\?\.\:\;\!\"\*\+\,]/g // in Dealtext
- ];
- var enBlack;
- var enWhite;
- var enBlackTemp;
- function EnstylerBlacklist() {
- // if logged in and user is not in whitelist
- if (enUserLogin && ! GM_config.get('enConfWhitelist').includes(enUserName)) {
- // add actual user to whitelist
- GM_config.set('enConfWhitelist', '@'+enUserName +',' + GM_config.get('enConfWhitelist'));
- //GM_config.setValue('enConfWhitelist', GM_config.get('enConfWhitelist'));
- }
- // convert Black/Whitelist to RegEx
- var myTemp=GM_config.get('enConfBlacklist');
- myTemp = myTemp.replace(unwantedRegex[0], '');
- myTemp = myTemp.replace(/^,|,$/g,'');
- enBlack = myTemp.replace(/(.),(.)/g,'$1|$2');
- myTemp=GM_config.get('enConfWhitelist');
- myTemp = myTemp.replace(/^,|,$/g,'');
- enWhite = myTemp.replace(/(.),(.)/g,'$1|$2');
- enBlackTemp= GM_config.get('enConfHideColder');
- EnstylerBlacklistDo();
- }
- function EnstylerBlacklistDo() {
- if (!GM_config.get('enConfBlackEnable')) { return;}
- // process every article
- $('article').each(function () {
- if ($(this).hasClass(enClassBlackDone)) { return;}
- var myThread = '#'+$(this).attr('id');
- // return if already done or return no deal
- if (!myThread.startsWith('#'+enDealMarker)) { return;}
- // mark as already seen
- $(this).addClass(enClassBlackDone);
- // get title, categorie, user
- var myDealText = $(myThread + ' .thread-category').text();
- myDealText += ' ' +$(myThread + ' .thread-title a').text();
- myDealText += ' @' +$(myThread + ' .user').text();
- myDealText = myDealText.replace(unwantedRegex[1] ,' ');
- // Whitelist first
- // whitelist Regex, exit if found
- if (enWhite !='' && myDealText.match(new RegExp(enWhite,'i'))) {
- return;
- }
- //get temp
- var myVoteTemp = $(myThread + ' .vote-temp').text();
- // blacklist vote temp
- if (parseInt(myVoteTemp) <= enBlackTemp) {
- $(this).addClass(enClassHidden);
- enBlacklisted++;
- EnstylerLastSeenSkip(myThread)
- return;
- }
- // blacklist last
- // blacklist Regex, rxit if found
- if (enBlack !='' && myDealText.match(new RegExp(enBlack,'i'))) {
- $(this).addClass(enClassHidden);
- enBlacklisted++;
- EnstylerLastSeenSkip(myThread)
- return;
- }
- }); // END Article
- // set label for unBlacklist button
- EnstylerBlacklistShow()
- }
- // blacklist support functions ....
- var enUnblackText = 'unBlacklist <NUM-BLACK> Dealz';
- function EnstylerBlacklistShow() {
- enJSfieldDefs.enConfUnblacklist.label=enUnblackText.replace('<NUM-BLACK>',enBlacklisted)
- }
- function EnstylerBlacklistRemove() {
- enBlacklisted=0;
- EnstylerBlacklistShow()
- $('.'+enClassHidden).removeClass(enClassHidden);
- $('.'+enClassBlackDone).removeClass(enClassBlackDone);
- }
- function EnstylerBlacklistUnhide() {
- enBlacklisted=0;
- EnstylerBlacklistShow()
- $('.'+enClassHidden).removeClass(enClassHidden);
- }
- // Main Nav will stay on TOP of the screen =========================
- function EnstylerFixedNav() {
- var myFixedCssMain='.nav { display: block; position: fixed; width: 100%; z-index: 120;} .subNav, .userProfile, .tabbedInterface {margin-top: 4.4em;}';
- var myFixedCssSub ='.subNav {margin-top: 0 !important;} .nav-subheadline {margin-top: 4.4em;}';
- if (GM_config.get('enConfNavFixed')) {
- // everywhere but in Deal detail, I like it like it is ...
- if (enSection != '/deals/' && enSection != '/gutscheine/' ){
- // delete header element with active stuff, but keep inside HTML
- var mySavedHtml = $('header').html();
- $('header').replaceWith(mySavedHtml);
- // CSS for everywhere
- addStyleString(myFixedCssMain);
- if (! enSection.match(enMainSectionMatch)) {
- // additional CSS for categories
- addStyleString(myFixedCssSub);
- }
- }
- }
- }
- // the return of "gestern xx:xx Uhr" ==============
- var enNow;
- var DealDate;
- var TodayStart;
- var ShowTime;
- var EnstylerTimeSeen='enTimeSeen';
- function EnstylerDealTime() {
- enNow = new Date();
- enNow.setTime(EnstylerStartTime)
- DealDate=new Date();
- TodayStart = new Date(enNow.getFullYear(), enNow.getMonth(), enNow.getDate());
- ShowTime= GM_config.get('enConfDealMinTime')*3600*1000;
- EnstylerDealTimeDo();
- }
- function EnstylerDealTimeDo() {
- if (GM_config.get('enConfDealTime')) {
- enNow.setTime(Date.now())
- // process every article
- $('time').each(function () {
- // get Deal time Diff, return if no diff or already seen
- var myTime= $(this).text();
- // next article
- if ( $(this).hasClass(EnstylerTimeSeen) || !myTime.startsWith('vor ')) { return;}
- // get Deal Time difference
- var h = myTime.replace(/.* ([0-9].*) h.*/, '$1'); if (h==myTime) h=0; else h=parseInt(h);
- var m = myTime.replace(/.* ([0-9].*) m.*/, '$1'); if (m==myTime) m=0; else m=parseInt(m);
- var s = myTime.replace(/.* ([0-9].*) s.*/, '$1'); if (s==myTime) s=0; else s=parseInt(s);
- // compose real deal time
- var myDealDiff = ((h*60+m)*60+s)*1000; // Offset deal
- DealDate.setTime( enNow.getTime() - myDealDiff );
- // last midnigth
- if (DealDate < TodayStart) {
- $(this).text('gestern '+ DealDate.toString().slice(16, 21) +' Uhr');
- // more than 6 hours ago
- } else if (myDealDiff > ShowTime){
- $(this).text(myTime + ' (heute '+ DealDate.toString().slice(16, 21) +' Uhr)');
- } else { return; }
- $(this).addClass(EnstylerTimeSeen);
- });
- }
- }
- // mark last seen Deal in Highligth, Hot and New ============================
- var enSec='off';
- var enSeenArticle='';
- // GM variables used here
- // store newest loaded deal
- // 'enNewestDeal...new'
- // 'enNewestDeal...hot'
- // 'enNewestDeal...'
- // international support added
- var enNewestBase='enNewest'+enLocParser.hostname.replace('www','');
- function EnstylerLastSeen(){
- // only in main categories
- if(enSection.match(enMainSectionMatch)) {
- // get section and save
- enSec= enNewestBase + enSection.replace(/\//, '');
- GM_setValue(enNewestBase+'LastSec', enSec)
- // mark last seen article
- enSeenArticle=GM_getValue(enSec);
- EnstylerLastSeenDo();
- // save actual last seen
- $('article').each(function () {
- // get ThreadID an return if not enDealMarker
- var myThread = $(this).attr('id');
- if (!myThread.startsWith(enDealMarker)) {return;}
- // when in base of section ...
- if(enLocParser.search == '') {
- //store actual seen
- GM_setValue(enSec, myThread);
- //store last seen
- GM_setValue(enSec+'Last', enSeenArticle);
- }
- // exit loop
- return false;
- });
- } else {
- // if we are not on base of ancategorie restore last value
- enSec=GM_getValue(enNewestBase+'LastSec');
- GM_setValue(enSec, GM_getValue(enSec+'Last'));
- }
- }
- function EnstylerLastSeenDo(){
- // only in main categories
- if(enSec != 'off') {
- // mark last seen article
- if ( typeof enSeenArticle != 'undefined') {
- //store last marked
- GM_setValue(enSec+'Last', enSeenArticle);
- $('#'+enSeenArticle).addClass('enClassMarkArticle');
- $('#'+enSeenArticle).prev().addClass('comments-marker');
- } else {
- // first time
- GM_setValue(enSec, enDealMarker+'1');
- }
- }
- }
- // article is not availible i.e. blacklisted
- function EnstylerLastSeenSkip(DealID) {
- // if article last seen one, skip to next
- if (DealID == '#'+enSeenArticle) {
- // magic, get ID of next article
- enSeenArticle=$(DealID).next().attr('id');
- if (DEBUG) console.error('Skip Deal: '+DealID.substr(1)+' -> '+enSeenArticle)
- EnstylerLastSeenDo();
- }
- }
- // AMAZON mobile redirect ==================================
- // workaround to not intercept myDealz redirects with GM_xmlhttp
- // stolen from amazon redirect mobile: https://greasyfork.org/de/scripts/19700
- function enAmazonMobileRedirect() {
- var enMyLocation=enLocParser.toString();
- // do we run on amazon?
- if (enMyLocation.startsWith("https://www.amazon")) {
- // redirect enabled?
- if (GM_config.get('enConfAmazonRedirect')) {
- // do it
- if (enMyLocation.includes("/gp/aw/d/")) { window.location.assign(enMyLocation.replace("/gp/aw/d/", "/dp/")) }
- else { window.location.assign(enMyLocation.replace("/gp/aw/ol/", "/gp/offer-listing/")); }
- }
- // Amazon but no redirect enabled
- return false;
- }
- return true;
- }
- // create button for display Config ======================
- var EnstylerButton = 'EnstylerButton';
- //var input = document.createElement('a');
- // input.setAttribute('href', 'showEnstylerConfig()');
- // input.setAttribute('id', EnstylerButton);
- var input = document.createElement('input');
- input.type = 'button';
- input.setAttribute('id', EnstylerButton);
- input.onclick = showEnstylerConfig;
- function EnstylerButtonCreate() {
- // add Enstyler Button to ...
- var myElement;
- var myMain=false;
- input.value = 'Enstyler';
- EnstylerButtonRemove();
- // MainNav or Deal
- if (GM_config.get('enConfBtn') || enSection.match(/deals\/|gutscheine\//))
- { myMain=true; }
- // only if space left
- if ($(window).width() < GM_config.get('enConfBtnMinWidth'))
- { myMain=false; }
- if (myMain) {
- // add button to MainNav
- var Elements = document.getElementsByClassName("navMenu-trigger");
- myElement=Elements[0];
- input.setAttribute('class', 'vAlign--all-m nav-link-text');
- input.setAttribute('style', '');
- } else {
- // add button to SubNav
- myElement = document.getElementById('tour-filter');
- input.setAttribute('class', 'box--all-i subNavMenu-link');
- input.setAttribute('style', 'font-size: 1.28571em; font-weight: 700; top: 3px; left: -0.7em');
- }
- // only if myElement exist
- if (myElement !== null) {
- myElement.appendChild(input);
- //insertAfter(input, myElement);
- }
- }
- // needed for Enstyler Homepage
- function EnstylerHomeButton() {
- // add Enstyler Button to ...
- input.value = 'Options';
- var myElement = document.getElementById('style-settings');
- input.setAttribute('style', 'font-size: 1.28571em; padding: 0.8em;');
- // only if myElement exist
- if (myElement !== null) {
- //myElement.appendChild(input);
- insertAfter(input, myElement);
- }
- }
- function EnstylerButtonRemove() {
- // Removes button from the document
- $('#'+ EnstylerButton).remove
- }
- // ============= GM_config functions =======================================
- var enJSAutoUpdate=GM_info.scriptWillUpdate;
- var enUpdateWindow;
- // define pattern for main sections here, incl. international support
- var enMainSectionMatch=/^\/$|^\/hot$|^\/new$|^\/settings$|^\/discussed$|^\/hei%C3%9F$|^\/diskutiert$/
- var enInternationalSite='';
- if(!enLocParser.hostname.match(/mydealz\.de/i)) {
- enInternationalSite=enLocParser.hostname.replace('www','');
- if(DEBUG) console.error('International Site detected: ' +enInternationalSite);
- }
- // define EnstylerJS GM_config elements
- var enJSfieldDefs = {
- // Part one: load external content --------
- 'enstyler': {
- 'section': ['additonal features for Enstyler', ''],
- 'label': 'Update CSS...', // Appears on the button
- 'type': 'button', // Makes this setting a button input
- 'click': function() { // Function to call when button is clicked
- enUpdateWindow=window.open('https://userstyles.org/styles/128262#style-info',
- 'UserCSS', 'width=600,height=950,left=0,top=0');
- }
- },
- 'enstylerJS': {
- 'label': 'Update UserScript...', // Appears on the button
- 'type': 'button', // Makes this setting a button input
- 'click': function() { // Function to call when button is clicked
- enUpdateWindow=window.open(!DEBUG ? 'https://greasyfork.org/de/scripts/24243' :
- ' https://greasyfork.org/scripts/24244-enstylerjs-develop/code/EnstylerJS Develop.user.js',
- 'UserScript', 'width=110,height=110,left=0,top=0');
- // give 2s to start update, then close
- sleepAsync(2000).then(() => { enUpdateWindow.close(); });
- }
- },
- 'dontCookies': {
- 'label': 'Mozilla no cookies...', // Appears on the button
- 'type': 'button', // Makes this setting a button input
- 'click': function() { // Function to call when button is clicked
- window.open('https://addons.mozilla.org/de/addon/i-dont-care-about-cookies/'); }
- },
- // part two: EnstylerJS internal configuration options ------
- 'Section': { // display next section, dont kow why ...
- 'section': ['Configuration', ''],
- 'type': 'hidden', // Makes this setting a hidden input
- },
- // postion of enstyler "button"
- 'enConfBtn': {
- 'label': 'Enstyler in MainNav', // Appears next to field
- 'type': 'checkbox', // Makes this setting a checkbox input
- 'default': false // Default value if user doesn't change it
- },
- 'enConfBtnMinWidth': {
- 'label': 'if width is bigger than ', // Appears next to field
- 'type': 'int', // Makes this setting a text input
- 'min': 600, // Optional lower range limit
- 'max': 1200, // Optional upper range limit
- 'size': 4, // Limit length of input (default is 25)
- 'default': 850 // Default value if user doesn't change it
- },
- 'enConfNavFixed': {
- 'label': 'Display FIXED MainNav', // Appears next to field
- 'type': 'checkbox', // Makes this setting a checkbox input
- 'default': true // Default value if user doesn't change it
- },
- // ehanced USerInfo
- 'enConfUser': {
- 'label': 'Show Popuop Userinfo', // Appears next to field
- 'type': 'checkbox', // Makes this setting a checkbox input
- 'default': true // Default value if user doesn't change it
- },
- 'enConfAvatar': {
- 'label': 'bigger Avatar for Popuop', // Appears next to field
- 'type': 'checkbox', // Makes this setting a checkbox input
- 'default': true // Default value if user doesn't change it
- },
- // enable filtering of external links
- 'enConfAmazonRedirect': {
- 'label': 'Amazon mobile redirect', // Appears next to field
- 'type': 'checkbox', // Makes this setting a checkbox input
- 'default': true // Default value if user doesn't change it
- }, // */
- // more Deal actions
- 'enConfMoreDeal': {
- 'label': 'additional Deal actions', // Appears next to field
- 'type': 'checkbox', // Makes this setting a checkbox input
- 'default': true // Default value if user doesn't change it
- }, // more Deal actions
- // show real Dealtime
- 'enConfDealTime': {
- 'label': 'Show real Deal Time', // Appears next to field
- 'type': 'checkbox', // Makes this setting a checkbox input
- 'default': true // Default value if user doesn't change it
- },
- 'enConfDealMinTime': {
- 'label': 'if older than Hours', // Appears next to field
- 'type': 'int', // Makes this setting a text input
- 'min': 1, // Optional lower range limit
- 'max': 24, // Optional upper range limit
- 'size': 4, // Limit length of input (default is 25)
- 'default': 6 // Default value if user doesn't change it
- },
- // Page picker
- 'enConfPagePicker': {
- 'label': 'Enable Page Picker', // Appears next to field
- 'type': 'checkbox', // Makes this setting a checkbox input
- 'default': true // Default value if user doesn't change it
- },
- // Black/Whitelist input
- 'enConfBlackEnable': {
- 'label': 'Enable Black- / Whitelist', // Appears next to field
- 'type': 'checkbox', // Makes this setting a checkbox input
- 'default': true // Default value if user doesn't change it
- },
- 'enConfHideColder': {
- 'label': 'Blacklist if colder then', // Appears next to field
- 'type': 'int', // Makes this setting a text input
- 'min': -9999, // Optional lower range limit
- 'max': -9, // Optional upper range limit
- 'size': 4, // Limit length of input (default is 25)
- 'default': -999 // Default value if user doesn't change it
- },
- 'enConfBlacklist': {
- 'label': 'Blacklist - deals, categories, @users', // Appears next to field
- 'type': 'text', // Makes this setting a text input
- 'size': 70, // Limit length of input (default is 25)
- 'default': 'Nutella, Bangood, @Admin' // Default value if user doesn't change it
- },
- 'enConfWhitelist': {
- 'label': 'Whitelist', // Appears next to field
- 'type': 'text', // Makes this setting a text input
- 'size': 70, // Limit length of input (default is 25)
- 'default': '' // Default value if user doesn't change it
- },
- 'enConfUnblacklist': {
- 'label': 'UnBlacklist', // Appears on the button
- 'type': 'button', // Makes this setting a button input
- 'click': function() { // Function to call when button is clicked
- EnstylerBlacklistUnhide(); }
- },
- // display copy message at end of section ...
- 'copy': {
- 'section': ['', '(c) Gnadelwartz - <a target="blank" href="https://www.mydealz.de/diskussion/enstyler2-style-your-mydealz-incl-pepper-sites-736219">Enstyler2 - Style your MyDealz</a>'],
- 'type': 'hidden', // Makes this setting a hidden input
- },
- };
- // define EnstylerJS GM_config elements
- var enHomefieldDefs = {
- // Part one: load external content --------
- 'saveOpt': {
- 'section': ['save your CSS options for next visit', ''],
- 'label': 'Select your CSS on main page then come back and klick "Save" ', // Appears near textarea
- 'type': 'textarea', // Makes this setting a button input
- 'size': 70,
- //'click': function() { // Function to call when button is clicked
- // showUrl('https://userstyles.org/styles/128262#style-info'); }
- },
- // display copy message at end of section ...
- 'copy': {
- 'section': ['', '(c) Gnadelwartz - <a target="blank" href="https://www.mydealz.de/diskussion/enstyler2-style-your-mydealz-incl-pepper-sites-736219">Enstyler2 - Style your MyDealz</a>'],
- 'type': 'hidden', // Makes this setting a hidden input
- 'value': 'Some hidden value' // Value stored
- },
- };
- // display GM_copnfig as div, so we can apply CSS easy!!
- var enGMOptChange = false;
- var enGMFrame = document.createElement('div');
- enGMFrame.setAttribute('class','GM_config');
- document.body.appendChild(enGMFrame);
- // basic config panel formatting, everything else is formatted by enstyler
- var enCSS = ['.GM_config {left: 5% !iportant; top: 9% !important; height: auto !important; max-width: 35em !important;}',
- '.GM_config input, .GM_config button, .GM_config textarea { border: 1px solid; margin: 0.5em 0em 0.2em 1em; padding: 0.1em;}',
- '.GM_config .reset { font-size: 9pt; padding-right: 1em; }',
- '.enClassHidden, #EnPopup_closeBtn {display: none;}',
- ].join(" ");
- addStyleString(enCSS);
- var En_Popup = new GM_configStruct(
- {
- 'id': 'EnPopup', // You need to use a different id for each instance
- 'title': 'EnstylerJS - Info',
- 'fields': // Fields object
- {
- 'Text': // This is the id of the field
- {
- 'label': '', // Appears next to field
- 'type': 'textarea', // Makes this setting a text field
- 'default': '' // Default value if user doesn't change it
- }
- },
- 'events':
- {
- 'open': function (doc) {
- // rename the buttons
- var config = this;
- doc.getElementById(config.id + '_saveBtn').textContent = ' OK ';
- //doc.getElementById(config.id + '_closeBtn').textContent = 'Cancel';
- doc.getElementById(config.id + '_resetLink').textContent = '';
- },
- 'save': function() {
- enUpdateChecked=false;
- enCheckUpdates();
- En_Popup.close();
- },
- 'close': function() { enGMConfigOpen=false;},
- },
- 'frame': enGMFrame // Element used for the panel
- }
- );
- function showPopup(text) {
- En_Popup.fields['Text'].value = text;
- En_Popup.fields['Text'].reload();
- En_Popup.open();
- }
- var enGMConfigOpen=false;
- // EnstylerJS Config Panel anzeigen
- function showEnstylerConfig() {
- if(!enGMConfigOpen) {
- enGetHome();
- GM_config.open();
- enGMConfigOpen=true;
- } else {
- GM_config.close();
- }
- }
- // EnstylerJS START ========================
- if (!window.location.hostname.endsWith('userstyles.org')) {
- var enFixedNav=false;
- GM_config.init(
- {
- // international sites support
- id: 'GM_config'+enInternationalSite,
- title: !DEBUG ? 'EnstylerJS - Settings' : ' EnstylerJS - >> Debug <<',
- fields: enJSfieldDefs,
- 'events': // Callback functions object
- {
- //'init': function() { alert('onInit()'); },
- // remove elements ich switch is checked or not
- 'open': function() {
- var enRemoveConfig = [
- // { check: true, switch: 'enConfFilterLink', remove: 'externalMobileRedirect'},
- { check: false, switch: 'enConfBtn', remove: 'enConfBtnMinWidth'},
- { check: false, switch: 'enConfUser', remove: 'enConfAvatar'},
- { check: false, switch: 'enConfDealTime', remove: 'enConfDealMinTime'},
- { check: false, switch: 'enConfBlackEnable', remove: 'enConfWhitelist'},
- { check: false, switch: 'enConfBlackEnable', remove: 'enConfBlacklist'},
- { check: false, switch: 'enConfBlackEnable', remove: 'enConfHideColder'},
- { check: false, switch: 'enConfBlackEnable', remove: 'enConfUnblacklist'}
- ];
- enFixedNav=GM_config.get('enConfNavFixed');
- // remove unneeded controls
- $(enRemoveConfig).each(function() {
- if (GM_config.get(this.switch) == this.check) {
- GM_config.fields[this.remove].remove();
- }
- });
- // remove / display update dialog
- if (enJSAutoUpdate) {GM_config.fields['enstylerJS'].remove();}
- },
- //'reset': function() { alert('reset') },
- // relaod page on close after save
- 'save': function() {
- // disabeling FixedNav can only done with reload
- if (!GM_config.get('enConfNavFixed') && GM_config.get('enConfNavFixed')!=enFixedNav) {window.location.reload(false);}
- // restart Enstyler magic
- EnstylerStart();
- EnstylerButtonCreate();
- EnstylerPagePickerCreate();
- // show changes in config after processing magic
- GM_config.close();
- GM_config.open();
- },
- 'close': function() { enGMConfigOpen=false;},
- },
- 'frame': enGMFrame // Element used for the panel
- }
- );
- // Enstyler internal Startup functions ======================
- // HACK: we are NOT on Amazon
- if (enAmazonMobileRedirect()) {
- // Basic Initialisation
- function EnstylerInit () {
- // hide Enstyler2 CSS (c) text because we have a button now
- addStyleString('.threadWidget-footer::after {display: none !important};');
- // get LoginStatus and Username
- if (enUserLogin = $('.avatar--type-nav').length) {
- enUserName = $('.navDropDown a').attr('href');
- enUserName = enUserName.replace(/.*\/profile\/([^\/]+).*/,'$1');
- if(DEBUG) console.error('User: ' +enUserName);
- }
- // get Section (first element in path)
- enSection= enLocParser.pathname.replace(/\/([^\/]+\/*).*/,'/$1');
- if(DEBUG) console.error('Section: ' +enSection);
- }
- // dummy, do not delete
- function enGetHome() {;}
- // Start Enstyler Magic
- function EnstylerStart() {
- EnstylerFixedNav();
- EnstylerDealTime();
- EnstylerLastSeen();
- EnstylerBlacklist();
- EnstylerAvatarPopup();
- EnstylerDealActions();
- }
- // delayed actions after finishing everything else
- function EnstylerDelayedInit() {
- // don't know why, but works only if called with delay ...
- EnstylerButtonCreate();
- EnstylerPagePickerCreate();
- // track DOM change Events, debounce: wait 1000ms after mutiple events
- // then re-apply (somse) changes to dynamic loaded content,
- if(DEBUG) console.error('DOMSubtreeModified INIT');
- $('.cept-event-deals, .thread-list--type-card').bind("DOMSubtreeModified",$.debounce( 300, function(){
- EnstylerLastSeenDo();
- EnstylerDealTimeDo();
- EnstylerBlacklistDo();
- EnstylerAvatarPopupDo();
- EnstylerDealActionsDo();
- EnstylerPagePickerCreateDo();
- if(DEBUG) console.error('DOMSubtreeModified executed');
- }));
- }
- // =============== MAIN: START EnstyerJS ===================
- EnstylerInit();
- EnstylerStart()
- // wait until page is loaded completely
- if (document.readyState == 'loading' || document.readyState == 'interactive'){ // Greasemonkey and Tampermonky -> runs script on DOM ready -> wait for load
- if(DEBUG) console.error('Run on DOM ready');
- $(window).bind("load", function() { EnstylerDelayedInit(); });
- }
- else { // if script run on page loaded -> give some time to finish rendering
- if(DEBUG) console.error('Run on Document loaded');
- sleepAsync(Date.now()-EnstylerStartTime).then(() => { EnstylerDelayedInit(); });
- }
- } // END Enstyler MAIN
- // ============= EnStyler UserScript Homepage functions =======
- // support for EnStyler2 export / import
- } else {
- // we are on ujserstyle
- function enGetHome() {
- var myOptions='';
- $('#style-settings select').each(function() {
- var myID = $(this).attr('id');
- var myValue = $('#'+myID).val();
- var myText = $('option[value='+ myValue +']').text();
- myOptions +='#' + myID + ':' + myValue +':' + myText +';\n';
- });
- $('#style-settings input:checked').each(function() {
- var myID = $(this).attr('id');
- var myValue = $('#'+myID).val();
- var myText = $('label[for='+ myID +']').text();
- myOptions +='#' + myID + ':' + myValue +':' + myText +';\n';
- });
- GM_config.set('saveOpt', myOptions);
- }
- function enSetHome() {
- // get saved options,remove newlines and split to settings array
- var myOptions=GM_config.get('saveOpt');
- myOptions=myOptions.replace(/\n/g,'');
- var mySettings = myOptions.split(';');
- // abort if no options found
- if (myOptions=='' || !myOptions.startsWith('#')) {return;}
- for (var i=0; i< mySettings.length; i++) {
- // each Setting has 3 fields seperated by :, but only 2 used
- var myField=mySettings[i].split(':');
- if (myField[0].match(/^#setting/i)) {
- // select
- $(myField[0]).val('');
- $(myField[0]).val(myField[1]);
- } else if (myField[0].startsWith('#option')) {
- // option
- $(myField[0]).prop('checked', true);
- } else {
- if (myField[0] != '') {alert('unkown option: "' + myField +'"');}
- }
- }
- }
- // close Window after Click on Update
- function UpdateOnClick () {
- sleepAsync(10000).then(() => { window.close(); });
- }
- $(".install").click (UpdateOnClick);
- // remove / display logo selection based on option
- function UpdateLogoSelection() {
- // selection is "Original"
- if ($('#setting-453429').val() == 'ik-flame1') {
- // hide logo selection
- $('#style-settings > li:last-child').addClass('enClassHidden');
- } else {
- // show logo selection
- $('#style-settings > li:last-child').removeClass('enClassHidden');
- }
- }
- $('#setting-453429').change(UpdateLogoSelection);
- // activate config for Enstyler Homepage
- GM_config.init(
- {
- id: 'GM_config',
- title: 'Enstyler2 - Settings',
- fields: enHomefieldDefs,
- 'events': // Callback functions object
- {
- //'init': function() { alert('onInit()'); },
- // remove elements ich switch is checked or not
- //'open': function() { enGetHome(); },
- //'reset': function() { enGMOptChange = true; },
- // relaod page on close after save
- 'save': function() { enSetHome(); GM_config.close();},
- 'close': function() { enGMConfigOpen=false; },
- },
- 'frame': enGMFrame // Element used for the panel
- }
- );
- // START Enstyler 2 Homepage
- EnstylerHomeButton();
- // set saved options
- enSetHome();
- // show/hide logo selection
- UpdateLogoSelection();
- }
- //=========== Support functions for actual use ======
- // add CSS in to document
- function addStyleString(str) {
- var node = document.createElement('style');
- node.innerHTML = str;
- document.body.appendChild(node);
- }
- // insertAfter like .insertBefore but as support function
- function insertAfter(newNode, referenceNode) {
- referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
- }
- // sleep time expects milliseconds, then execute code
- // NOTE: code runs in parallel (asnyc)!
- // Usage!
- // sleepAsync(500).then(() => {
- // Do something after the sleep!
- // });
- function sleepAsync (time) {
- return new Promise((resolve) => setTimeout(resolve, time));
- }