@@ -8,6 +8,47 @@ import Layout from './layout.vue'
88import '@theojs/lumen/theme'
99import '@theojs/lumen/doc-blocks-border'
1010
11+ /**
12+ * Add noopener to links with text fragments
13+ */
14+ function initNoopenerLinks ( ) {
15+ if ( typeof window === 'undefined' )
16+ return
17+
18+ const processLinks = ( ) => {
19+ document . querySelectorAll ( 'a' ) . forEach ( ( link ) => {
20+ const href = link . getAttribute ( 'href' )
21+ // Add noopener to links with text fragments
22+ if ( href && href . includes ( ':~:text=' ) ) {
23+ const rel = link . getAttribute ( 'rel' ) || ''
24+ if ( ! rel . includes ( 'noopener' ) ) {
25+ const newRel = rel ? `${ rel } noopener` : 'noopener'
26+ link . setAttribute ( 'rel' , newRel . trim ( ) )
27+ }
28+ const target = link . getAttribute ( 'target' ) || ''
29+ if ( ! target ) {
30+ link . setAttribute ( 'target' , '_blank' )
31+ }
32+ }
33+ } )
34+ }
35+
36+ // Process links on load
37+ if ( document . readyState === 'loading' ) {
38+ document . addEventListener ( 'DOMContentLoaded' , processLinks )
39+ }
40+ else {
41+ processLinks ( )
42+ }
43+
44+ // Process dynamically added links
45+ const observer = new MutationObserver ( processLinks )
46+ observer . observe ( document . body , {
47+ childList : true ,
48+ subtree : true ,
49+ } )
50+ }
51+
1152export default {
1253 extends : DefaultTheme ,
1354 Layout,
@@ -17,6 +58,8 @@ export default {
1758 baiduAnalytics ( { baiduId : '0afa8cd5bd78fd0c960f8af5dc6af333' } )
1859 if ( typeof window !== 'undefined' ) {
1960 trackPageview ( '0afa8cd5bd78fd0c960f8af5dc6af333' , window . location . href )
61+ // Initialize noopener for text fragment links
62+ initNoopenerLinks ( )
2063 }
2164
2265 app . component ( 'Home' , HomeUnderline )
0 commit comments