Jump to content

MediaWiki:Common.js: Difference between revisions

The comprehensive free global encyclopedia of CEOs, corporate leadership, and business excellence
Added polling mechanism to wait for canvas element (fixes timing issue)
JavaScript now creates canvas element dynamically (bypasses MediaWiki HTML escaping)
Line 46: Line 46:


/**
/**
  * Simple 3D Rotating Tag Cloud - With Polling for Canvas Element
  * 3D Rotating Tag Cloud - Creates Canvas Dynamically
  */
  */
(function() {
(function() {
Line 64: Line 64:
      
      
     var attempts = 0;
     var attempts = 0;
     var maxAttempts = 50; // Try for 5 seconds (50 * 100ms)
     var maxAttempts = 50;
      
      
     function tryInitialize() {
     function tryInitialize() {
         attempts++;
         attempts++;
          
          
         var canvas = document.getElementById('tagcanvas');
        // Look for the placeholder div
         if (!canvas) {
         var placeholder = document.getElementById('ceocloud-placeholder');
         if (!placeholder) {
             if (attempts < maxAttempts) {
             if (attempts < maxAttempts) {
                 console.log('[TagCloud] Canvas not found yet, retrying... (attempt ' + attempts + '/' + maxAttempts + ')');
                 console.log('[TagCloud] Placeholder not found yet, retrying... (attempt ' + attempts + '/' + maxAttempts + ')');
                 setTimeout(tryInitialize, 100);
                 setTimeout(tryInitialize, 100);
             } else {
             } else {
                 console.error('[TagCloud] Canvas element not found after ' + maxAttempts + ' attempts. Giving up.');
                 console.error('[TagCloud] Placeholder div not found after ' + maxAttempts + ' attempts. Giving up.');
             }
             }
             return;
             return;
         }
         }
          
          
         console.log('[TagCloud] Canvas found after ' + attempts + ' attempts! Initializing...');
         console.log('[TagCloud] Placeholder found after ' + attempts + ' attempts! Creating canvas...');
          
          
         // Hide the fallback list
         // Create canvas element dynamically
         var ul = canvas.querySelector('ul');
         var canvas = document.createElement('canvas');
         if (ul) {
         canvas.id = 'tagcanvas';
            ul.style.display = 'none';
        canvas.width = 800;
            console.log('[TagCloud] Fallback list hidden');
        canvas.height = 400;
        }
        canvas.style.maxWidth = '100%';
        canvas.style.height = 'auto';
       
        // Clear placeholder and add canvas
        placeholder.innerHTML = '';
        placeholder.appendChild(canvas);
       
        console.log('[TagCloud] Canvas created and added to DOM');
          
          
         var ctx = canvas.getContext('2d');
         var ctx = canvas.getContext('2d');
Line 301: Line 309:
     }
     }
      
      
     // Start trying to find the canvas
     // Start trying to find the placeholder
     tryInitialize();
     tryInitialize();
})();
})();

Revision as of 10:56, 20 October 2025

/**
 * Add statistics banner to account creation page
 */
(function() {
    // Only run on Special:CreateAccount page
    if (typeof mw !== 'undefined' && mw.config && mw.config.get('wgCanonicalSpecialPageName') !== 'CreateAccount') {
        return;
    }

    if (typeof mw !== 'undefined' && mw.Api && typeof $ !== 'undefined') {
        // Get site statistics via API
        var api = new mw.Api();

        api.get({
            action: 'query',
            meta: 'siteinfo',
            siprop: 'statistics',
            format: 'json'
        }).done(function(data) {
            var stats = data.query.statistics;

            // Create statistics banner
            var banner = $('<div>').addClass('createaccount-statistics').html(
                '<div class="createaccount-statistics-title">CEO.wiki is made by people like you.</div>' +
                '<div class="createaccount-statistics-grid">' +
                    '<div class="createaccount-stat-item">' +
                        '<div class="createaccount-stat-number">' + stats.edits.toLocaleString() + '</div>' +
                        '<div class="createaccount-stat-label">Edits</div>' +
                    '</div>' +
                    '<div class="createaccount-stat-item">' +
                        '<div class="createaccount-stat-number">' + stats.pages.toLocaleString() + '</div>' +
                        '<div class="createaccount-stat-label">Pages</div>' +
                    '</div>' +
                    '<div class="createaccount-stat-item">' +
                        '<div class="createaccount-stat-number">' + stats.activeusers.toLocaleString() + '</div>' +
                        '<div class="createaccount-stat-label">Recent Contributors</div>' +
                    '</div>' +
                '</div>'
            );

            // Insert banner before the form
            $('#userloginForm').before(banner);
        });
    }
})();

/**
 * 3D Rotating Tag Cloud - Creates Canvas Dynamically
 */
(function() {
    'use strict';
    
    console.log('[TagCloud] Script loaded');
    
    // Check if we're on Main Page
    if (typeof mw !== 'undefined' && mw.config) {
        var pageName = mw.config.get('wgPageName');
        console.log('[TagCloud] Page name:', pageName);
        if (pageName !== 'Main_Page') {
            console.log('[TagCloud] Not Main Page, exiting');
            return;
        }
    }
    
    var attempts = 0;
    var maxAttempts = 50;
    
    function tryInitialize() {
        attempts++;
        
        // Look for the placeholder div
        var placeholder = document.getElementById('ceocloud-placeholder');
        if (!placeholder) {
            if (attempts < maxAttempts) {
                console.log('[TagCloud] Placeholder not found yet, retrying... (attempt ' + attempts + '/' + maxAttempts + ')');
                setTimeout(tryInitialize, 100);
            } else {
                console.error('[TagCloud] Placeholder div not found after ' + maxAttempts + ' attempts. Giving up.');
            }
            return;
        }
        
        console.log('[TagCloud] Placeholder found after ' + attempts + ' attempts! Creating canvas...');
        
        // Create canvas element dynamically
        var canvas = document.createElement('canvas');
        canvas.id = 'tagcanvas';
        canvas.width = 800;
        canvas.height = 400;
        canvas.style.maxWidth = '100%';
        canvas.style.height = 'auto';
        
        // Clear placeholder and add canvas
        placeholder.innerHTML = '';
        placeholder.appendChild(canvas);
        
        console.log('[TagCloud] Canvas created and added to DOM');
        
        var ctx = canvas.getContext('2d');
        if (!ctx) {
            console.error('[TagCloud] Could not get 2D context');
            return;
        }
        
        var width = canvas.width;
        var height = canvas.height;
        
        console.log('[TagCloud] Canvas size:', width, 'x', height);
        
        // Tags configuration
        var tags = [
            { text: 'Satya Nadella', url: '/wiki/Satya_Nadella', size: 24 },
            { text: 'Tim Cook', url: '/wiki/Tim_Cook', size: 22 },
            { text: 'Elon Musk', url: '/wiki/Elon_Musk', size: 26 },
            { text: 'Mark Zuckerberg', url: '/wiki/Mark_Zuckerberg', size: 20 },
            { text: 'Sundar Pichai', url: '/wiki/Sundar_Pichai', size: 20 },
            { text: 'Andy Jassy', url: '/wiki/Andy_Jassy', size: 18 },
            { text: 'Jensen Huang', url: '/wiki/Jensen_Huang', size: 22 },
            { text: 'Lisa Su', url: '/wiki/Lisa_Su', size: 18 },
            { text: 'Mary Barra', url: '/wiki/Mary_Barra', size: 18 },
            { text: 'Jamie Dimon', url: '/wiki/Jamie_Dimon', size: 18 },
            { text: 'Microsoft', url: '/wiki/Microsoft', size: 16 },
            { text: 'Apple', url: '/wiki/Apple_Inc.', size: 16 },
            { text: 'Amazon', url: '/wiki/Amazon', size: 16 },
            { text: 'Google', url: '/wiki/Google', size: 16 },
            { text: 'Tesla', url: '/wiki/Tesla', size: 16 },
            { text: 'Leadership', url: '/wiki/Category:Chief_executive_officers', size: 14 },
            { text: 'Innovation', url: '/wiki/Category:Business_strategies', size: 14 },
            { text: 'Technology', url: '/wiki/Category:Companies', size: 14 },
            { text: 'Strategy', url: '/wiki/Category:Business_strategies', size: 14 },
            { text: 'Cloud Computing', url: '/wiki/Category:Industry_analysis', size: 14 }
        ];
        
        // Initialize 3D positions
        var radius = 180;
        var dtr = Math.PI / 180;
        var mcList = [];
        var lasta = 1;
        var lastb = 1;
        var tspeed = 0.5;
        var size = 250;
        var mouseX = 0;
        var mouseY = 0;
        var active = false;
        
        // Build tag objects
        for (var i = 0; i < tags.length; i++) {
            var oTag = {};
            oTag.offsetWidth = tags[i].size * 5;
            oTag.offsetHeight = tags[i].size;
            oTag.text = tags[i].text;
            oTag.url = tags[i].url;
            oTag.size = tags[i].size;
            mcList.push(oTag);
        }
        
        var sa, ca, sb, cb, sc, cc;
        
        function sineCosine(a, b, c) {
            sa = Math.sin(a * dtr);
            ca = Math.cos(a * dtr);
            sb = Math.sin(b * dtr);
            cb = Math.cos(b * dtr);
            sc = Math.sin(c * dtr);
            cc = Math.cos(c * dtr);
        }
        
        function positionAll() {
            var phi = 0;
            var theta = 0;
            var max = mcList.length;
            
            for (var i = 0; i < max; i++) {
                phi = Math.acos(-1 + (2 * i + 1) / max);
                theta = Math.sqrt(max * Math.PI) * phi;
                
                mcList[i].cx = radius * Math.cos(theta) * Math.sin(phi);
                mcList[i].cy = radius * Math.sin(theta) * Math.sin(phi);
                mcList[i].cz = radius * Math.cos(phi);
            }
        }
        
        function doPosition() {
            ctx.clearRect(0, 0, width, height);
            
            for (var i = 0; i < mcList.length; i++) {
                var tag = mcList[i];
                var x = tag.x + width / 2;
                var y = tag.y + height / 2;
                
                var alpha = Math.max(0.2, Math.min(1, tag.alpha));
                var fontSize = Math.max(10, tag.size * tag.scale);
                
                ctx.save();
                ctx.font = fontSize + 'px sans-serif';
                ctx.fillStyle = 'rgba(255, 255, 255, ' + alpha + ')';
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
                ctx.shadowBlur = 4;
                ctx.shadowOffsetX = 0;
                ctx.shadowOffsetY = 2;
                ctx.fillText(tag.text, x, y);
                ctx.restore();
                
                tag.cx = x;
                tag.cy = y;
            }
        }
        
        function depthSort() {
            mcList.sort(function(a, b) {
                return (b.cz - a.cz);
            });
        }
        
        function update() {
            var a, b;
            
            if (active) {
                a = (-Math.min(Math.max(-mouseY, -size), size) / radius) * tspeed;
                b = (Math.min(Math.max(-mouseX, -size), size) / radius) * tspeed;
            } else {
                a = lasta * 0.98;
                b = lastb * 0.98 + 0.01;
            }
            
            lasta = a;
            lastb = b;
            
            if (Math.abs(a) <= 0.01 && Math.abs(b) <= 0.01) {
                return;
            }
            
            var c = 0;
            sineCosine(a, b, c);
            
            for (var i = 0; i < mcList.length; i++) {
                var rx1 = mcList[i].cx;
                var ry1 = mcList[i].cy * ca + mcList[i].cz * (-sa);
                var rz1 = mcList[i].cy * sa + mcList[i].cz * ca;
                
                var rx2 = rx1 * cb + rz1 * sb;
                var ry2 = ry1;
                var rz2 = rx1 * (-sb) + rz1 * cb;
                
                var rx3 = rx2 * cc + ry2 * (-sc);
                var ry3 = rx2 * sc + ry2 * cc;
                var rz3 = rz2;
                
                mcList[i].cx = rx3;
                mcList[i].cy = ry3;
                mcList[i].cz = rz3;
                
                var per = size / (size + rz3);
                
                mcList[i].x = rx3 * per;
                mcList[i].y = ry3 * per;
                mcList[i].scale = per;
                mcList[i].alpha = per;
                mcList[i].alpha = (mcList[i].alpha - 0.6) * (10 / 6);
            }
            
            doPosition();
            depthSort();
        }
        
        // Event handlers
        canvas.onmouseover = function() {
            active = true;
        };
        
        canvas.onmouseout = function() {
            active = false;
        };
        
        canvas.onmousemove = function(ev) {
            var rect = canvas.getBoundingClientRect();
            mouseX = ev.clientX - rect.left - width / 2;
            mouseY = ev.clientY - rect.top - height / 2;
        };
        
        canvas.onclick = function(ev) {
            var rect = canvas.getBoundingClientRect();
            var mx = ev.clientX - rect.left;
            var my = ev.clientY - rect.top;
            
            for (var i = 0; i < mcList.length; i++) {
                var tag = mcList[i];
                var dx = mx - tag.cx;
                var dy = my - tag.cy;
                var dist = Math.sqrt(dx * dx + dy * dy);
                
                if (dist < 50) {
                    window.location.href = tag.url;
                    break;
                }
            }
        };
        
        canvas.style.cursor = 'pointer';
        
        // Initialize
        sineCosine(0, 0, 0);
        positionAll();
        setInterval(update, 30);
        
        console.log('[TagCloud] Successfully initialized! Animation started. You should see tags rotating now!');
    }
    
    // Start trying to find the placeholder
    tryInitialize();
})();