-
Notifications
You must be signed in to change notification settings - Fork 3
/
amazon-clean-ui.user.js
511 lines (467 loc) · 19 KB
/
amazon-clean-ui.user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
// ==UserScript==
// @name Amazon - Clean UI
// @namespace https://openuserjs.org/users/zachhardesty7
// @author Zach Hardesty <[email protected]> (https://github.com/zachhardesty7) <[email protected]> (https://github.com/zachhardesty7)
// @description removes annoying largely not useful elements from Amazon
// @copyright 2019-2021, Zach Hardesty (https://zachhardesty.com/)
// @license GPL-3.0-only; http://www.gnu.org/licenses/gpl-3.0.txt
// @version 1.9.0
// @homepageURL https://github.com/zachhardesty7/tamper-monkey-scripts-collection/raw/master/amazon-clean-ui.user.js
// @homepageURL https://openuserjs.org/scripts/zachhardesty7/Amazon_-_Clean_UI
// @supportURL https://github.com/zachhardesty7/tamper-monkey-scripts-collection/issues
// @updateURL https://openuserjs.org/meta/zachhardesty7/Amazon_-_Clean_UI.meta.js
// @downloadURL https://openuserjs.org/src/scripts/zachhardesty7/Amazon_-_Clean_UI.user.js
// @include https://*amazon.com*
// @require https://greasyfork.org/scripts/419640-onelementready/code/onElementReady.js?version=887637
// ==/UserScript==
let STYLES = ""
let READY = false
const QUEUE = []
/**********************
* helper functions *
**********************/
/**
* read from global `STYLES` and append string to document head as CSS
*
* @returns {void}
*/
const attachStyles = () => {
const stylesheet = document.createElement("style")
const head = document.head || document.querySelectorAll("head")[0]
stylesheet.id = "hiding" // to edit later
stylesheet.type = "text/css"
stylesheet.append(document.createTextNode(STYLES))
head.append(stylesheet)
}
/**
* retrieves node from selector or passes through el(s) or false otherwise,
* designed to allow repeatedly calling on return value without breaking
*
* @param {DOMTargetItem} target - selector or el
* @param {number} i - position of item to return if selector finds multiple matches
* @returns {HTMLElement | object | boolean} targeted DOM el or input object or false otherwise
*/
const getElX = (target, i = 0) =>
typeof target === "string" ? document.querySelectorAll(target)[i] : target
/**
* retrieves nodes from selector or passes through el(s) or false otherwise,
* designed to allow repeatedly calling on return value without breaking
*
* @param {DOMTargetItems} target - selector or els
* @returns {HTMLElement[]} targeted DOM el or input object or false otherwise
*/
const getElAll = (target) => {
if (typeof target === "string") return [...document.querySelectorAll(target)]
if (target instanceof Element) return [target]
return [...target]
}
/**
* adds an event listener func to a given selector (if it exists)
* NOTE: queues event if page not loaded
*
* @param {DOMTargetItem} target - selector or els
* @param {string} event - trigger to listen for
* @param {Function} func - executed after event trigger
* @returns {void}
*/
const on = (target, event, func) => {
const statement = () => {
const el = getElX(target)
if (el && el.addEventListener) el.addEventListener(event, func)
}
READY ? statement() : QUEUE.push(statement)
}
/**
* sets property on a given selector (if it exists)
* NOTE: queues action if page not loaded
*
* @param {DOMTargetItem} target - selector or el
* @param {string} attr - trigger to listen for
* @param {string} val - desired property value
* @param {number} i - position of item to assign to if selector finds multiple matches
* @returns {void}
*/
const setAttrX = (target, attr, val, i = 0) => {
const statement = () => {
const el = getElX(target, i)
if (el) el[attr] = val
}
READY ? statement() : QUEUE.push(statement)
}
/**
* sets style on a given selector (if it exists), extends setAttr
* NOTE: queues action if page not loaded
*
* @param {DOMTargetItem} target - selector or el
* @param {string} val - desired style property value
* @param {number} i - position of item to assign to if selector finds multiple matches
* @returns {void}
*/
const setStyleX = (target, val, i = 0) => {
setAttrX(target, "style", val, i)
}
/**
* sets style on a given selector via a StyleSheet
*
* @param {DOMTargetItem} target - selector or els
* @param {string} val - desired style property value
* @returns {void}
*/
const setStyle = (target, val) => {
STYLES += `
${target} {
${val}
}
`
}
/**
* sets style to 'display: none' on a given selector (if it exists), extends setStyle
* NOTE: queues action if page not loaded
*
* @param {DOMTargetItem} target - selector or el
* @param {number} i - position of item to hide if selector finds multiple matches
* @returns {void}
*/
const hideX = (target, i = 0) => {
setStyleX(target, "display: none !important;", i)
}
/**
* sets style to `display: none !important;` on a given selector via a StyleSheet,
*
* @param {DOMTargetItem} target - selector or el
* @returns {void}
*/
const hide = (target) => {
setStyle(target, "display: none !important;")
}
/**
* sets style to 'display: none' on a given selector's `X`
* parent (if chain exists), extends setStyle
* NOTE: queues action if page not loaded
*
* @param {DOMTargetItem} target - selector or el
* @param {number} x - vertical upward depth of item from child to hide
* @param {number} i - position of item to assign to if selector finds multiple matches
* @returns {void}
*/
const hideParentX = (target, x = 0, i = 0) => {
const statement = () => {
let el = getElX(target, i)
for (let count = 0; count < x; count += 1) {
el = el && el.parentElement
}
hideX(el)
}
READY ? statement() : QUEUE.push(statement)
}
/**
* sets style to 'display: none' on each given selector's `X`
* parent (if chain exists), extends setStyle
* NOTE: queues action if page not loaded
*
* @param {DOMTargetItem} target - selector or el
* @param {number} x - vertical upward depth of item from child to hide
* @returns {void}
*/
const hideAllParentX = (target, x = 0) => {
const statement = () => {
for (const el of getElAll(target)) {
hideParentX(el, x)
}
}
READY ? statement() : QUEUE.push(statement)
}
/**
* create functions to add null checking and prevent script errors
*
* @typedef {string | NodeListOf<HTMLElement> | HTMLElement | HTMLElement[] | null} DOMTargetItems
* @typedef {string | HTMLElement | null} DOMTargetItem
*/
function addElementsToHideQueue() {
const link = window.location.href
// product-based pages
if (
/https*:\/\/.*?amazon\.com\/dp\/.*/g.test(link) ||
/https*:\/\/.*?amazon\.com\/gp\/product\/.*/g.test(link) ||
/https*:\/\/.*?amazon\.com\/.*\/dp\/.*/g.test(link)
) {
// hide nav junk / banner ads
hide("#navSwmHoliday")
hide("#universal-detail-ilm")
hide("#detail-ilm_div")
// hideX("#dp div", 0) // TODO: eats whole page sometimes
hideX("#dp div", 1) // TODO: dangerous, replace with more precise selector
// hide sharing
hide("#tellAFriendBox_feature_div")
hide("#tellAFriendBylineBox_feature_div")
// hide product sales help & options nobody uses (protection plan, etc)
hide("#image-canvas-caption")
hide("#issuancePriceblockAmabot_feature_div")
hide("#alternativeOfferEligibilityMessaging_feature_div")
hide("#productSupportAndReturnPolicy_feature_div")
hide("#smileEligibility_feature_div")
hide("#addServices_feature_div")
hide("#edpIngress_feature_div")
hide("#hqpWrapper")
hide("#HLCXComparisonJumplink_feature_div")
hide("#olp_feature_div")
hide(
"#moreBuyingChoices_feature_div > div > .a-section.a-padding-base:first-child"
)
hide("#hqp")
hide("#mbb_feature_div")
hide("#simpleBundle_feature_div")
hide("#buyNow_feature_div")
hide("#oneClick_feature_div")
hideParentX("#oneClickSignIn", 1)
hide("#glowContextualIngressPt_feature_div")
hide("#digitalDashLowProminence_feature_div")
hide("#digitalDashLowProminenceAccordion_feature_div")
hide("#digital-dash-create-high-prominence")
hide("#buyNow")
hideParentX("#add-to-registry-wedding-button", 2)
hideParentX(".oneclick-guide", 1)
hideParentX(".oneclick-guide", 2, 1)
hide("#tradeInInstantSavings_feature_div")
hide("#digital-dash-create")
hide("#tradeInButton_feature_div")
hide("#add-to-baby-button-group")
hide("#productSupportInsideMOBB_feature_div") // tech support included
hide("#cpsiaProductSafetyWarning_feature_div") // choking hazard
hide("#b2bUpsell_feature_div") // save w business acct
// getEl('.a-column.a-span6.a-span-last').lastElementChild.style = 'display: none'
// misc ads -- does not prevent loading or tracking
hide("#amsDetailRight_feature_div")
hide("#dp-ads-center-promo_feature_div")
hide("#ape_Detail_dp-ads-center-promo_Desktop_placement")
hide("#ADPlaceholder")
hide("#ape_Detail_ad-endcap-1_Glance_placement")
hide("#productAlert_feature_div") // amazon hub
// clean up empty section dividers
setStyle(".bucket", "display: block;")
hide(".bucketDivider")
hide("#promoGrid")
hide("#messages")
// hide related products and recommendations
hide("#sp_detail_thematic")
hide("#skyCitySoftMerge_feature_div")
hide("#recommendations_feature_div")
hide(".a-section.similarities-widget")
hide('[name="goKindleStaticPopDiv"]:first-child')
hide("#sims-fbt")
hide("#heroQuickPromoBooksAtf_feature_div") // book suggestion under product summary
hide("#heroQuickPromo_feature_div") // get alexa for Win10
hide("#bundleV2_feature_div")
hide("#cerberus_feature_div")
hide("#p13n-m-desktop-dp-sims_session-similarities-sims-feature-3")
hide("#p13n-m-desktop-dp-sims_purchase-similarities-sims-feature-3")
hide("#p13n-m-desktop-dp-sims_purchase-similarities-sims-feature-2")
hide("#relatedMaterials_feature_div")
hide("#beautyRecommendations_feature_div")
hide("#rhf")
hide("#sponsoredProducts2_feature_div")
hide("#sims-consolidated-2_feature_div")
hide("#dpx-btf-hlcx-comparison_feature_div")
hide("#HLCXComparisonWidget_feature_div")
hide("#featureAwarenessWidget_feature_div")
hideParentX("#widget_container .a-carousel-container", 1)
hideX(".a-section", getElAll(".a-section").length - 5)
hide("#beautyBadging_feature_div") // Luxury Beauty green tag
hide("#almMultiOfferEgress_feature_div") // "other ways to buy"
hide("#ccxssContent") // post ATC recommendations panel
// hide('#attach-accessories') // post ATC recommendations panel FIXME: broken due to lazy load
// REVIEW: experimental, hide junk at the bottom of the page without ID or class
hide("#dpx-giveaway_feature_div ~ div")
hide("#dpx-giveaway_feature_div ~ table")
// TEST: sub components already hidden, hiding parent makes weird spacing
// hide("#va-related-videos-widget_feature_div") // videos for related products
hide("#rvs-vse-related-videos") // videos for this item and related products
hide(".threepsl.MultiBrandCreativeDesktop.celwidget") // brands related to category
hide(".threepsl.MultiBrandLifestyleCreativeDesktop.celwidget") // brands related to category
hide(".thirdPartySponsorLink--twoAds") // brands related to category
hide('[cel_widget_id="desktop-dp-sims_amazonlive-percolate-detail-page"]') // live streams
hide('[cel_widget_id="desktop-dp-sims_SponsoredProductsSimsDpDesktop"]') // related products
hide('[cel_widget_id="desktop-dp-sims_day0-sims-6523"]') // page w related products bottom text
hide(
'[cel_widget_id="desktop-dp-sims_SponsoredProductsSimsDpDesktopThematic"]'
) // 4 star related prods
hide("#valuePick_feature_div") // similar item to consider
// hide other junk sections
hide("#sp_detail")
hide("#quickPromoBucketContent")
hideParentX(".celwidget .a-section.askDetailPageSearchWidgetSection", 1)
hide("#vse-related-videos")
hide("#vseVideoWidget_cardDeck")
hide(".a-section.vse-empty-view-container.bucket:first-child")
hide("#importantInformation")
hide("#giveaway_feature_div")
hide("#view_to_purchase-sims-feature")
hide("#store-disclaimer_feature_div")
hideParentX("#fiona-publisher-signup-link", 2)
hideParentX("#hero-quick-promo-grid_feature_div #hero-quick-promo", 1)
hide("#extraProductInfoTxtBookFeatureGroup")
setStyle("#aplus", "padding: 15px 0; border-top: lightgrey 1px solid;")
setStyle("#reviewsMedley", "margin-bottom: 0 !important;")
hide("#superleafProductAlert_feature_div")
hide("#dpx-legal_feature_div")
hide("#cm_cr_skyfall_medley .cr-skyfall-feedback-section") // is feedback helpful? // FIXME:
hide("#flipAndSampleAudio")
hide("#authorFollow_feature_div")
hide(".askQuestionExamples:first-child")
hide("#acBadge_feature_div")
hide("#hsxShCelDpAmznCertBdg") // works w alexa
hide("#dpx-smarthome-hub_feature_div") // add alexa for voice control
hide("#pldn-deep-link") // suggestion to use smile
hide("#productDetailsTable td.bucket div.content div.bucket") // better price & seller support links
hide("#moreBuyingChoices_feature_div") // have one to sell?
hide("#trialBox") // report copyright issues
// remove unnatural black background of title bar on some pages (video game consoles)
setStyle("#ppd-top", "background: none;")
setStyle("#titleBar.superleaf", "background: none;")
setStyle(
".superleafParent #wayfinding-breadcrumbs_container",
"background: none;"
)
// fix colors
setStyle(
".superleafParent #wayfinding-breadcrumbs_feature_div .a-color-tertiary",
"color: #111 !important;"
)
setStyle(
"a#breadcrumb-back-link.a-link-normal.a-color-tertiary",
"color: #111 !important;"
)
setStyle(
"#superLeafTitleFeatureGroup #titleSection #title",
"color: black;"
)
setStyle(
"#titleBar.superleaf .a-color-secondary:first-child",
"color: #555 !important;"
)
setStyle("#titleBar-left", "color: black;")
setStyle(
"#superLeafGameReviews_feature_div .a-icon-popover:first-child",
"filter: none;"
)
setStyle(
"#titleBar a:link, #titleBar.superleaf .a-link-normal",
"color: #0066c0 !important;"
)
setStyle(".superleaf .ac-for-text:first-child", "color: #888;")
setStyle(
"#superleafActionPanelWrapper",
"box-shadow: rgba(0, 0, 0, 0.45) 0px 0px 4px -1px;"
)
}
// subscribe & save page
if (/https*:\/\/.*?amazon\.com\/gp\/subscribe-and-save\/.*/g.test(link)) {
// onElementReady('#recommendations', false, e => hide(e))
// setStyle('.a-section.deliveries', 'margin-bottom: 0px;')
// console.log('test')
hide("#recommendations") // all main sections
// hideParentX('.a-section.deliveries > div.a-fixed-right-grid') // history related
}
// search page
if (/https*:\/\/.*?amazon\.com\/s.*/g.test(link)) {
hide(".AdHolder")
hide("#centerBelowExtra") // search feedback
hide('div[data-component-type="sp-sponsored-result"]') // sponsored res
hide(
'#rhf[aria-label="Your recently viewed items and featured recommendations"]'
) // footer full of junk
hideAllParentX(".a-section #pdagEncapsulated .slot__ad", 2)
hideAllParentX(
".s-result-item .sg-col-inner .celwidget div .s-shopping-adviser",
4
) // editorial recs
hideAllParentX(".s-result-item .sg-col-inner div .s-shopping-adviser", 3) // similar connectors
hideAllParentX(
'.s-result-item .sg-col-inner div .sg-row .sg-col .sg-col-inner .a-section .s-visual-card-navigation-carousel-title-wrapper div[aria-label*="Search for"]',
8
) // search in a category
hideAllParentX(
'span[data-component-type="s-bottom-slot"] .a-section span[data-component-type="s-searchgrid-carousel"]',
2
) // inspired by your views
hideAllParentX(
'span[data-component-type="s-brand-footer-slot"] .a-section #thirdPartySponsorLinkOuter',
2
) // related brands
hide('span[data-component-type="s-feedback-slot"]') // feedback
hideAllParentX('span[data-component-type="s-ads-metrics"]', 1) // sponsored product search brand (little giant)
hideAllParentX("div[data-ad-feedback]", 1) // sponsored product search brand (little giant)
// div.a-section.a-spacing-none.s-result-item.s-flex-full-width.s-widget.s-widget-spacing-large:nth-of-type(1)
// #ad-feedback-text-auto-sparkle-hsa-tetris
hideAllParentX('[cel_widget_id="MAIN-VIDEO_SINGLE_PRODUCT"]', 1) // sponsored product search brand (little giant)
// .a-section.sbv-product .sbv-ad-feedback
hideAllParentX('[cel_widget_id="MAIN-FEEDBACK"]', 1) // sponsored product search brand (little giant)
}
// wishlist page
if (/https*:\/\/.*?amazon\.com\/hz\/wishlist\/ls.*/g.test(link)) {
// hide recommendations
hide("#rhf")
hide("#loaded-items")
// increase spacing of filter icon
setStyle("#filter-and-sort span:first-child", "padding-right: 5px;")
}
// ideas page
if (/https*:\/\/.*?amazon\.com\/ideas\/.*/g.test(link)) {
hide("#rhf") // hide recommendations
}
/* site-wide modifications */
// hide nav ads
hide("#nav-upnav")
hide("#nav-subnav")
hide("#nav-main") // delivery location & useless links
// hide("#nav-main .nav-right")
// hide recent items
hide("#raw-sitewide-rhf")
// minimize size and hide useless giant footer section
setStyle("#navFooter", "margin-top: 0px;")
hideX(".navFooterLine.navFooterLinkLine.navFooterPadItemLine")
hideX(".navFooterLine.navFooterLinkLine.navFooterDescLine")
setStyle(
"#navFooter.navLeftFooter .navFooterCopyright",
"padding-bottom: 10px !important;"
)
// hide generally useless last remaining part of footer section
hideX("#navFooter .navFooterVerticalColumn.navAccessibility")
hideX("#navFooter .navFooterCopyright")
setStyleX(".nav-footer-line", "margin-top: 0px;")
setStyleX("#navBackToTop div", "margin-bottom: 0px;")
// add button to allow footer display restore
setAttrX(
"#navFooter .nav-footer-line",
"innerHTML",
`
<a
id='view-footer'
style='color: #fff; padding: 15px 0; display: block; text-align: center;'
>
View Footer Site Links
</a>
`
)
// activate button to restore footer display
QUEUE.push(() =>
on(getElX("#view-footer"), "click", () => {
hideX("#view-footer")
setStyleX(".nav-footer-line", "margin-top: 30px;")
setStyleX("#navBackToTop div", "margin-bottom: 30px !important;")
setStyleX(
"#navFooter .navFooterVerticalColumn.navAccessibility",
"display: table;"
)
})
)
if (STYLES) attachStyles()
}
window.addEventListener("load", executeHideElementsJS)
addElementsToHideQueue()
function executeHideElementsJS() {
READY = true
for (const statement of QUEUE) {
statement()
}
}