Search code examples
javascriptjquerymediawikijsfiddle

Code working on jsfiddle.net doesn't work locally


I'd like to play around locally with this code I found. To present it quickly, the code reproduce the front end of a wikipedia page in a minimalistic fashion. I tried the code in Brackets, without any modification except the basic tags (<html>, <script>,<body>) and the linking of the jquery library in the same version than the mini wiki code, here is the code I use :

<!DOCTYPE html>


<html>
    <head>  
        <title> example</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    </head>
    
    <body>
        <div class='container'>
            <h1 id="title">MiniWiki</h1>
        <div id="content"></div>
        </div>
        
        <script>
            var titleElem = document.getElementById('title');
            var contentElem = document.getElementById('content');
            var stylesheetElem = document.getElementById('style');
            function extractTitle(title) {
                return title.replace(/(^.\/)|(#.*$)/g, '').replace(/_/g, ' ');
            }
            function loadPage(title) {
                var url = 'https://en.wikipedia.org:443/api/rest_v1/page/html/' + encodeURIComponent(title);
                return $.ajax(url).then(function (data) {
                    var doc = (new DOMParser()).parseFromString(data, 'text/html');
                    // Use mediawiki content stylesheet
                    $(stylesheetElem).remove();
                    stylesheetElem = doc.querySelector('head link[rel="stylesheet"]');
                    $('head').append(stylesheetElem);
                    // Update title and content
                    $(titleElem).text(doc.title.replace(/^User:Cscott\//, '').replace(/_/g, ' '));
                    var $content = $(contentElem).empty();
                    Array.from(doc.body.attributes).forEach(function (attr) {
                        $content.attr(attr.name, attr.value);
                    });
                    $content.append(Array.from(doc.body.children));
                    // Handle redirects
                    $('link[rel="mw:PageProp/redirect"]').replaceWith(function() {
                        return $('<a rel="mw:WikiLink">REDIRECT</a>').attr('href', $(this).attr('href'));
                    });
                    // Add click handler to wiki links
                    $('a[rel="mw:WikiLink"]', $content).click(function (e) {
                        var newTitle = extractTitle($(e.currentTarget).attr('href'));
                        History.pushState(null, newTitle, "?title="+encodeURIComponent(newTitle));
                        return false; // Don't use normal href handler
                    });
                });
            }
            // Make the back button work
            History.replaceState(null, '', ''); // Ensure a state change later
            $(window).on('statechange', function() {
                loadPage(History.getState().title);
            });
            // Load the start page
            History.replaceState(null, 'User:Cscott/MiniWiki', '');
        </script>


    </body>
</html>

When trying this code, I keep having the following error in the console :

mini-wiki.html:51 Uncaught TypeError: History.replaceState is not a function

I noticed that by replacing History.replaceState, by history.replaceState, I could get rid of the error, but then, I have no errors left in the console and only the <h1> content is displayed.

Is there any reasons why this code is working flawlessly on jsfiddle.net and not locally ?


Solution

  • I tried to remove the jquery.history.js file and replace it with the jquery that you're importing in your script tag and it throws the error you're mentioning.

    I think you need to include the jquery.history.js file, that was included in the jsfiddle.

    I would recommend that you try importing the following line into your head tag:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/history.js/1.8/bundled-uncompressed/html4+html5/jquery.history.js"></script>