@@ -43,6 +43,40 @@ class GitHubGitLabTheme {
4343 this.setupNavigationListener();
4444 }
4545
46+ isRepositoryPage() {
47+ const pathname = window.location.pathname;
48+
49+ // Check for user profile repositories page
50+ if (pathname.match(/^\/[^\/]+$/)) {
51+ const pageHeader = document.querySelector('h1');
52+ if (pageHeader && pageHeader.textContent.includes('Repositories')) {
53+ return true;
54+ }
55+ }
56+
57+ // Check for user repositories tab
58+ if (pathname.includes('?tab=repositories')) {
59+ return true;
60+ }
61+
62+ // Check for organization repositories page
63+ if (pathname.includes('/orgs/') &&
64+ (pathname.includes('/repositories') ||
65+ document.querySelector('[data-test-selector="org-repositories-list"]'))) {
66+ return true;
67+ }
68+
69+ // Check for repository list containers
70+ const repoContainers = [
71+ '#user-repositories-list',
72+ '#org-repositories-list',
73+ '[data-testid="repository-list-container"]',
74+ 'div[data-test-selector="org-repositories-list"]'
75+ ];
76+
77+ return repoContainers.some(selector => document.querySelector(selector));
78+ }
79+
4680 setupNavigationListener() {
4781 // Listen for URL changes (GitHub is an SPA)
4882 let currentUrl = window.location.href;
@@ -55,7 +89,7 @@ class GitHubGitLabTheme {
5589 this.run();
5690 }, 500);
5791 }
58- } ) . observe ( document , { subtree : true , childList : true } ) ;
92+ }).observe(document.body , { subtree: true, childList: true });
5993 }
6094
6195 applyDarkTheme() {
@@ -182,10 +216,25 @@ class GitHubGitLabTheme {
182216 await this.saveSetting('customGroups', Array.from(this.customGroups));
183217 }
184218
185- run ( ) {
219+ run() {
220+ // Only run on repository-related pages
221+ if (!this.isRepositoryPage()) {
222+ console.log('[GitLab Theme] Not a repository page, skipping processing');
223+ return;
224+ }
225+
186226 // Apply dark theme first
187227 this.applyDarkTheme();
188228
229+ // Check if we're on an organization page for debugging
230+ const isOrgPage = window.location.pathname.includes('/orgs/') ||
231+ window.location.pathname.match(/^\/[^\/]+$/) &&
232+ document.querySelector('[data-test-selector="org-header"]');
233+
234+ if (isOrgPage) {
235+ console.log('[GitLab Theme] Organization page detected');
236+ }
237+
189238 // Setup observer for dynamic content
190239 this.setupMutationObserver();
191240
@@ -194,7 +243,7 @@ class GitHubGitLabTheme {
194243 this.processRepositories();
195244 }
196245
197- setupMutationObserver ( ) {
246+ setupMutationObserver() {
198247 if (this.observer) this.observer.disconnect();
199248
200249 this.observer = new MutationObserver((mutations) => {
@@ -211,36 +260,56 @@ class GitHubGitLabTheme {
211260 if (shouldProcess) {
212261 if (this.debounceTimer) clearTimeout(this.debounceTimer);
213262 this.debounceTimer = setTimeout(() => {
214- this . addGroupControls ( ) ;
215- this . processRepositories ( ) ;
263+ // Only process if we're still on a repository page
264+ if (this.isRepositoryPage()) {
265+ this.addGroupControls();
266+ this.processRepositories();
267+ }
216268 }, 300);
217269 }
218270 });
219271
220- this . observer . observe ( document . body , {
221- childList : true ,
222- subtree : true
272+ // Only observe specific containers, not the entire body
273+ const targetSelectors = [
274+ '#user-repositories-list',
275+ '#org-repositories-list',
276+ '[data-testid="repository-list-container"]',
277+ 'div[data-test-selector="org-repositories-list"]',
278+ 'main[role="main"]'
279+ ];
280+
281+ targetSelectors.forEach(selector => {
282+ const element = document.querySelector(selector);
283+ if (element) {
284+ this.observer.observe(element, {
285+ childList: true,
286+ subtree: true
287+ });
288+ }
223289 });
224290 }
225291
226- findRepositoryContainers ( ) {
292+ findRepositoryContainers() {
227293 const selectors = [
228294 '#user-repositories-list',
229295 '#org-repositories-list',
230296 '[data-testid="repository-list-container"]',
231- '.repo-list' ,
232297 '[data-filterable-for="your-repos-filter"]',
298+ '[data-filterable-for="org-repos-filter"]',
233299 '.js-repo-list',
234300 'ul[data-test-selector="profile-repository-list"]',
235- 'div[aria-label="Repositories"]'
301+ 'div[aria-label="Repositories"]',
302+ // Org page specific selectors
303+ 'div[data-test-selector="org-repositories-list"]',
304+ '[data-test-selector="org-repo-list"]'
236305 ];
237306
238307 const containers = [];
239308 selectors.forEach(selector => {
240309 try {
241310 const elements = document.querySelectorAll(selector);
242311 elements.forEach(el => {
243- if ( el && ! this . processedContainers . has ( el ) ) {
312+ if (el && !this.processedContainers.has(el) && this.isValidRepositoryContainer(el) ) {
244313 containers.push(el);
245314 this.processedContainers.add(el);
246315 }
@@ -250,9 +319,16 @@ class GitHubGitLabTheme {
250319 }
251320 });
252321
322+ console.log(`[GitLab Theme] Found ${containers.length} repository containers`);
253323 return containers;
254324 }
255325
326+ isValidRepositoryContainer(container) {
327+ // Check if container has repository items
328+ const repoItems = this.findRepositoryItems(container);
329+ return repoItems.length > 0;
330+ }
331+
256332 findRepositoryItems(container) {
257333 const itemSelectors = [
258334 '[itemprop="owns"]',
@@ -264,15 +340,21 @@ class GitHubGitLabTheme {
264340 '.fork',
265341 '.archived',
266342 'li[itemprop="owns"]',
267- 'div[data-testid="repository-item"]'
343+ 'div[data-testid="repository-item"]',
344+ // Org page specific selectors
345+ 'li[data-test-selector="repository-list-item"]',
346+ 'div[data-test-selector="repository-list-item"]',
347+ '.Box-row', // GitHub uses Box-row for repo items on org pages
348+ 'li[itemprop="codeRepository"]',
349+ 'div[itemprop="codeRepository"]'
268350 ];
269351
270352 let items = [];
271353 itemSelectors.forEach(selector => {
272354 try {
273355 const found = container.querySelectorAll(selector);
274356 found.forEach(item => {
275- const nameElement = item . querySelector ( 'h3 a, a[itemprop="name codeRepository"], .wb-break-all a, [data-testid="repository-name"]' ) ;
357+ const nameElement = item.querySelector('h3 a, a[itemprop="name codeRepository"], .wb-break-all a, [data-testid="repository-name"], [itemprop="name"], .Link--primary ');
276358 if (nameElement && !items.includes(item)) {
277359 items.push(item);
278360 }
@@ -285,7 +367,7 @@ class GitHubGitLabTheme {
285367 return items;
286368 }
287369
288- processRepositories ( ) {
370+ processRepositories() {
289371 if (this.isProcessing) return;
290372 this.isProcessing = true;
291373
@@ -299,12 +381,15 @@ class GitHubGitLabTheme {
299381 const items = this.findRepositoryItems(container);
300382
301383 if (items.length > 0) {
302- if ( this . groupingEnabled ) {
303- this . createGroupCards ( container , items ) ;
304- } else {
305- this . displayAllRepos ( container , items ) ;
384+ // Only process if container hasn't been processed already
385+ if (!container.dataset.gitlabProcessed) {
386+ if (this.groupingEnabled) {
387+ this.createGroupCards(container, items);
388+ } else {
389+ this.displayAllRepos(container, items);
390+ }
391+ container.dataset.gitlabProcessed = 'true';
306392 }
307- container . dataset . gitlabProcessed = 'true' ;
308393 }
309394 });
310395
@@ -315,46 +400,56 @@ class GitHubGitLabTheme {
315400 }
316401 }
317402
318- createGroupCards ( container , items ) {
403+ createGroupCards(container, items) {
319404 const groups = this.extractGroups(items);
320405
321406 if (groups.size <= 1) {
322407 this.displayAllRepos(container, items);
323408 return;
324409 }
325410
326- // Clear existing content
327- container . innerHTML = '' ;
328- container . classList . add ( 'gitlab-grouped-repositories' ) ;
329-
330- const fragment = document . createDocumentFragment ( ) ;
411+ // Store original content and clear container safely
412+ const originalContent = container.innerHTML;
413+ const originalClasses = container.className;
331414
332- // Create group cards section
333- const groupCardsSection = this . createGroupCardsSection ( groups , container ) ;
334- fragment . appendChild ( groupCardsSection ) ;
415+ try {
416+ container.innerHTML = '' ;
417+ container.classList.add('gitlab-grouped-repositories' );
335418
336- // Create hidden repo containers for each group
337- const repoContainersSection = this . createRepoContainers ( groups , container ) ;
338- fragment . appendChild ( repoContainersSection ) ;
419+ const fragment = document.createDocumentFragment();
420+
421+ // Create group cards section
422+ const groupCardsSection = this.createGroupCardsSection(groups, container);
423+ fragment.appendChild(groupCardsSection);
339424
340- container . appendChild ( fragment ) ;
425+ // Create hidden repo containers for each group
426+ const repoContainersSection = this.createRepoContainers(groups, container);
427+ fragment.appendChild(repoContainersSection);
341428
342- // Show the first group by default
343- const firstGroup = Array . from ( groups . keys ( ) ) [ 0 ] ;
344- console . log ( `[GitLab Theme] Auto-showing first group: ${ firstGroup } ` ) ;
345-
346- // Wait a bit for DOM to settle, then simulate first group click
347- setTimeout ( ( ) => {
348- console . log ( `[GitLab Theme] Attempting to show first group...` ) ;
349- const firstCard = container . querySelector ( `.gitlab-group-card[data-group-id="${ firstGroup } "]` ) ;
350- if ( firstCard ) {
351- console . log ( `[GitLab Theme] Found first group card, simulating click` ) ;
352- firstCard . click ( ) ;
353- } else {
354- console . error ( `[GitLab Theme] Could not find first group card: ${ firstGroup } ` ) ;
355- console . log ( `[GitLab Theme] Available cards:` , container . querySelectorAll ( '.gitlab-group-card' ) ) ;
356- }
357- } , 200 ) ;
429+ container.appendChild(fragment);
430+
431+ // Show the first group by default
432+ const firstGroup = Array.from(groups.keys())[0];
433+ console.log(`[GitLab Theme] Auto-showing first group: ${firstGroup}`);
434+
435+ // Wait a bit for DOM to settle, then simulate first group click
436+ setTimeout(() => {
437+ console.log(`[GitLab Theme] Attempting to show first group...`);
438+ const firstCard = container.querySelector(`.gitlab-group-card[data-group-id="${firstGroup}"]`);
439+ if (firstCard) {
440+ console.log(`[GitLab Theme] Found first group card, simulating click`);
441+ firstCard.click();
442+ } else {
443+ console.error(`[GitLab Theme] Could not find first group card: ${firstGroup}`);
444+ console.log(`[GitLab Theme] Available cards:`, container.querySelectorAll('.gitlab-group-card'));
445+ }
446+ }, 200);
447+ } catch (error) {
448+ console.error('[GitLab Theme] Error creating group cards, reverting to original content:', error);
449+ container.innerHTML = originalContent;
450+ container.className = originalClasses;
451+ this.displayAllRepos(container, items);
452+ }
358453 }
359454
360455 extractGroups(items) {
@@ -568,7 +663,12 @@ class GitHubGitLabTheme {
568663 reposSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
569664 }
570665
571- displayAllRepos ( container , items ) {
666+ displayAllRepos(container, items) {
667+ // Only modify if we haven't already processed this container
668+ if (container.dataset.gitlabProcessed === 'true') {
669+ return;
670+ }
671+
572672 const fragment = document.createDocumentFragment();
573673
574674 items.forEach(item => {
@@ -593,12 +693,15 @@ class GitHubGitLabTheme {
593693 'h3 a',
594694 'a[itemprop="name codeRepository"]',
595695 '.wb-break-all a',
596- '[data-testid="repository-name"]'
696+ '[data-testid="repository-name"]',
697+ '[itemprop="name"]',
698+ '.Link--primary',
699+ 'a[href*="/"][title]'
597700 ];
598701
599702 for (const selector of nameSelectors) {
600703 const element = item.querySelector(selector);
601- if ( element ) {
704+ if (element && element.textContent.trim() ) {
602705 return element.textContent.trim();
603706 }
604707 }
@@ -635,7 +738,10 @@ class GitHubGitLabTheme {
635738 const repoSections = [
636739 '#user-repositories-list',
637740 '#org-repositories-list',
638- '[data-testid="repository-list-container"]'
741+ '[data-testid="repository-list-container"]',
742+ 'div[data-test-selector="org-repositories-list"]',
743+ '.org-repos',
744+ '#org-repositories'
639745 ];
640746
641747 for (const selector of repoSections) {
0 commit comments