Coder Social home page Coder Social logo

djax's Introduction

#djax: Dynamic pjax

##Basic usage

djax is very quick to set up, with a few markup requirements to let it work smoothly.

First include it in your header after jquery:

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="jquery.djax.js"></script>

Then instantiate on the largest page element where you will have updating content. 'body' is typically the way to go with this:

<script type="text/javascript">
    jQuery(document).ready(function($) {
        $('body').djax('.updatable', ['array', 'of', 'url', 'fragments', 'to', 'exclude']);
    });
</script>

Congrats, you're done! Well mostly...

##Markup

djax will track elements with the class you pass it as a first argument. In the above example I've passed the class 'updatable,' so my markup would look something like this:

<body>
    <div class="wrapper" id="main">
        <div class="updatable first" id="first">
            Here's a div that will be monitored for changes by djax.
        </div>
        <div class="updatable second" id="second">
            Here's another
        </div>
    </div>
    <div class="sidebar" id="sidebar-right">
        <ul class="updatable sidebar-list">
            <li>Everything in this sidebar...</li>
            <li>is also being tracked</li>
            <li>Some pages might not have this ul</li>
            <li>That's fine, it just won't show on them</li>
        </ul>
    </div>

Your markup can be laid out however you like, and your trackable sections can be anywhere in relation to one another. It's best to keep them top level (nesting is unnecessary and unsupported,) and there are a few requirements that allow the plugin to function properly.

###IDs

Trackable elements must all have IDs. This is how the requested page is matched up with the current page. Only trackable elements that differ between the two pages will be loaded. Trackable elements that do not exist on the requested page will be removed, and trackable elements that do not exist on the current page will be added. In order to support this, it is also necessary to ensure the parent elements of every trackable element has an ID, as well as the sibling element immediately prior to each trackable element (if one exists).

These ID's are used to add elements when necessary. If an element exists in a requested page, but not the current page, it will be inserted after the prior sibling (by ID,) or prepended to the parent element (by ID.)

##Parameters

The plugin accepts only two parameters, and only one is required.

###Tracking Class

The first and only required parameter is the class you will use to identify trackable elements. If my code looks like the below sample, every dynamic element in my markup should have a class of djaxable

<script type="text/javascript">
    jQuery(document).ready(function($) {
        $('body').djax('.djaxable');
    });
</script>

###Exceptions

By default djax works on any internal links, but sometimes you may want to exclude certain URLs on your site. The second parameter allows you to pass an array of URL fragments to exclude from djax loading. This is performed with a simple Javascript 'indexOf,' so the more of the URL you provide, the more specifically your exclusions will be matched. The below example will djax any internal links that do not contain admin, resources, or ?s= in the url.

<script type="text/javascript">
    jQuery(document).ready(function($) {
        $('body').djax('.djaxable', ['admin', 'resources', '?s=']);
    });
</script>

##DOM Replacement Callbacks (optional)

Pass in a reference to a function that will handle the DOM replacement logic. The default djax replacement uses the standard jQuery replaceWith and does an immediate replace. For transitions, fade in/outs etc, you can control when and how the new content displays on the page. The following example fades out the old content, and fades in the new content.

<script type="text/javascript">
    var transition = function($newEl) {
        var $oldEl = this;      // reference to the DOM element that is about to be replaced
        $newEl.hide();    // hide the new content before it comes in

        $oldEl.fadeOut("fast", function() {
            $oldEl.replaceWith($content);
            $newEl.show();
            $newEl.fadeIn("fast");
        });
    }
    jQuery(document).ready(function($) {
        $('body').djax('.djaxable', [], transition);
    });
</script>

##Events

###djaxLoad

By loading new content via ajax, your visitors will only encounter $('document').ready() the first time they land on your site, and any time they manually perform a hard refresh. To help address this, djax triggers a window level event on each partial load it performs. Here's an example of enabling pageview tracking with Google Analytics on a djax enabled site:

$(window).bind('djaxLoad', function(e, data) {
    _gaq.push(['_trackPageview']);
});

As a convenience, the data object passed with the event contains the requested url, the page title for the requested page, and the contents of the requested page as a string. Use something like the following code to work with the response as a jQuery object

$(window).bind('djaxLoad', function(e, data) {
    var responseObj = $('<div>'+data.response+'</div>');
    //do stuff here
});

###djaxClick

This event is triggered when a djax'ed link is clicked. Use something like the code below to scroll top before loading in new content with ajax:

$(window).bind('djaxClick', function(e, data) {
        var bodyelem = ($.browser.safari) ? bodyelem = $("body") : bodyelem = $("html,body");
        bodyelem.scrollTop(0);	
});

##Live Demo

djax arose out of a desire to use pjax with complicated and varied layouts. See here for a WordPress site using a modified version of the bones WordPress theme. djax enabling this theme took about 28 lines of code (if you count adding a class to an element as a line of code.)

There is also a small working example in the github repository. Feel free to load up any of the included html files in your browser to see how it works.

djax's People

Contributors

beezee avatar garyjones avatar tony2nite avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

djax's Issues

how can i say dont use djax for target="blank" link

hi i want to open some internal link in new window without old page reload
but it is not posible for now, do you have any solition for this ?

example: < a href="site-com/sitemap.xml" target="_blank">Sitemap< /a>

i found a solution with this but its not good, every time page reload :)


$('body').on('click', 'a[target^=_blank], a[rel^=external], function(e) {  
        window.open($(this).attr('href'));
    location.reload();
        return false;
      });   

DOM replacement callbacks

I'm not able to achieve page transitions with the mentioned DOM replacement callbacks, resp. the example in the documentation or from your demo site. The callback function (e.g. "transition") doesn't seem to have any impact and an immediate content replace still occurs. Any ideas what's wrong with that or what I'm missing?

pjax wrapper?

It's not clear if djax is just a pjax wrapper for complicated layouts? Do I get the same pushState functionality? Thanks!

Djax thrown off by exceptions with hyphens

Hi there beezee, from what I can tell, djax does not recognize internal link exceptions with hyphens in the page name.

$('body').djax('.updateable', ['xml-sitemap','united-nations'], transition);

Djax apparently will ignore the 'xml-sitemap' and 'united-nations'; however, partial names, such as 'xml' and 'united' do work. The problem with this is the potential for name clashes. The apparent solution is to escape the hyphen with a backwards slash.

$('body').djax('.updateable', ['xml\-sitemap','united\-nations'], transition);

This works for me, though it is not made clear that this needs to be done. I'm guessing this is common knowledge for people working with js/jquery; however, it might be helpful to bake in special character escaping into djax.

scroll to location links within djax page

I am trying to use simple "click link to go to different location on the page" on one of my pages using djax, but it does not seem to work. Looks like there is some conflict.

To show what i want to achieve, here is the markup from one of my pages:

<div class="one-third column" id="middle">

        <a href="#s1">Section 1</a>
        <a href="#s2">Section 2</a>
        <a href="#s3">Section 3</a>

        <h1 id="s1">Header 1</h1>
        <p>Lorem Ipsum</p>

        <h1 id="s2">Header 2</h1>
        <p>Lorem Ipsum</p>

        <h1 id="s3">Header 3</h1>
        <p>Lorem Ipsum</p>

</div>

Is this even possible while using djax?

Thanks for any help, and nice script!

jQuery .click() handler not firing on DJAX-loaded page

DJAX is brilliant and really easy to use—thank you!

However, event handlers are not firing for me on a DJAX-loaded page. .click() and .keydown() are two that I've noticed so far.

If I visit a page URL directly (entering it in the URL bar), all the event handlers work perfectly. They stop working (don't seem to get triggered) on a DJAX-loaded page, unless I re-bind them using the djaxLoad event, in which case everything loads fine.

Any ideas on why this is, and how to fix it?

Thanks!

Grabbing full page HTM

Hello!

Great plugin from what I've seen. Thank you for the great work and the time you have spent on developing this. I'm having a small issue, but it's probably something on my end. It won't seem to update the content.

I'm using this code below. Fairly simple as you can see. I pretty much copied and pasted it from your example. I'm using this on a Wordpress site. When I click on a link, I see in the console, I see "Object" with the URL, Title, and the markup for the entire page. Just like what I see on your Wordpress example. I'm using the same class, and I placed the wrapper with the class "updatable" in the header.php and closing in the footer.php. Alternatively, I tried putting the wrapper on each template, like the github example on your site. (Took only 28 lines). That didn't work either. Do each templates have to be pretty much the same? Do I have to add the class to individual items that match throughout templates?

Any help would be much appreciated. Thank you.


$('body').djax('.updatable', ['wp-admin', 'wp-login', '?s=', 'pdf','doc','eps','png','zip','admin','feed']);

```
$(window).bind('djaxLoad', function(e, data) {
    console.log('triggered');
    console.log(data);
});
```

how to refresh header scripts

Hi ! this is not an issue but general question. How to refresh / reload wordpress header scripts on specific pages for example a have a google maps script loading on a map page (page-map.php template with "if ( is_page_template('page-map.php') )"condition) only.

Add credits and version to jquery.djax.js

I'd really like to be able to use djax in a WordPress plugin, but I'd like to see your jQuery plugin file contain:

  • credits for the author, including a URL back to this repo
  • a version string
  • a license indicator (hopefully GPL2 or later)

so that your excellent code can be properly attributed :-)

Djax $.get on an image

Hello,

I can't figure it out why the djax click on an image returns a response like this:
�����JExif��II*���������������2�����������:���(���������������H�������H����������,Photoshop 3.0�8BIM���������H�������H�������� XICC_PROFILE����� HLino����mntrRGB XYZ ����� ���1��acspMSFT����IEC sRGB�����������������������-HP ������������������������������������������������cprt���P���3desc�������lwtpt��������bkpt��������rXYZ��������gXYZ���,����bXYZ���@����dmnd���T���pdmdd��������vued���L����view�������$lumi��������meas��� ���$tech���0��� rTRC���<��� gTRC���<��� bTRC���<��� text����Copyright (c) 1998 Hewlett-Packard Company��desc��������sRGB IEC61966-2.1������������sRGB IEC61966-2.1��������������������������������������������������XYZ �������Q��������XYZ ����������������XYZ ������o���8�����XYZ ������b���������XYZ ������$���������desc��������IEC http://www.iec.ch������������IEC http://www.iec.ch����������������������������������������������desc�������.IEC 61966-2.1 Default RGB colour space - sRGB�����������.IEC 61966-2.1 Default RGB colour space - sRGB����������������������desc�������,Reference
...

On Wordpress it's working well, but I moved to Laravel and this is not working anymore.
Any help, would be appreciated.

Thanks!

External Link with the same URL

Hi, I make my new portfolio with this fantastic script.

But I have a little issue, I have an page with a link with target="_blank" but when click the page load inside the content, and I want to not load the page inside the content and load the new page into new tab.

A solution for this?

Create externs file for djax function

/**
 * @fileoverview Externs for jQuery djax plugin
 *
 * @externs
 */

/**
 * @param {string} selector
 * @param {Array.<string>=} exceptions
 * @return {jQuery}
 */
jQuery.prototype.djax = function (selector, exceptions) {};

I believe the above, saved into a new file jquery.djax.externs.js in your repo, will allow Closure Compiler config blocks on JS files that call djax(), to be able to be compiled without losing reference to the function name.

e.g.

// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @output_file_name foobar-djax.js
// @externs_url http://closure-compiler.googlecode.com/svn/trunk/contrib/externs/jquery-1.7.js
// @externs_url https://raw.github.com/beezee/djax/master/jquery.djax.externs.js
// ==/ClosureCompiler==
// http://closure-compiler.appspot.com/home

Djax the url changes but the contents of the page did not

Here's a snippet of the markup

<div id="resultContent" class='updatable'></div>
<ul>
    <li><a id="thankyou" href="views/thankyou.jsp?menuId=2"
        targets="resultContent">Thank You Message</a></li>
</ul>
When I click that the url changes but the result is not showing but when I view the page source it displays the proper markup(or should I say the markup of thankyou.jsp)

here is the code that Is js code

jQuery(document).ready(function($) {
$('body').djax('.updatable');
});

the url changes and when I view the page source it also changes but the page itself did not change its contents even if I view the page source it has change up any ideas why?

Script/Style Changes in WordPress themes

Hi beezee,
First off, this is pretty damn awesome.

I collaborated with another developer on getting PJAX to work with the Roots Theme, Roots PJAX, but unfortunately never really took off. The problem we ran into was since WordPress not only can, but encourages conditionally loading scripts/styles on certain pages, making sure we hooked into anything set by wp_enqueue_scripts() (as a very top-level example, being loaded in the header, footer -- or as introduced in WP 3.3, within the body as well) were left out. Does using DJAX run any checks for these types of things? Thanks!

Reinitialize or Remove djax?

I am loading some content in via AJAX (not using djax). This content contains links that I'd like to have djax do its thing with. Is there are way to reinitialize or remove/add-back djax? If I just call the djax method a second time, all the events fire twice. Any ideas?

Exceptions do not work

I want to exclude some links to images that should be opened with Fancybox, but they still get the "dJax_internal" class.

This is the code i'm using:

jQuery(document).ready(function($) {
    $('body').djax('.updatable', ['assets']);
});

Example image link:

a href="assets/templates/wwaw/images/1_b.jpg" class="fancybox" data-fancybox-group="gallery" title="Lorem ipsum dolor sit amet">

Is this a bug or am I doing something wrong?

Doesn't work with trackable elements that are direct children of body

While setting up my views for those occasions when I simply want to replace all of the page content rather than small portions, I found that a direct child of body can't be used as a trackable element:

<body id="body">
  <div id="main" class="updateable">

So I'm using an extra div that I otherwise wouldn't have done:

<body>
  <div id="main-wrapper">
    <div id="main" class="updateable">

I don't know if you'd want or be able to accommodate using direct children of body, but thought I'd mention it anyway as I spent a little while trying to get it to work before I figured it out, so it may be worth mentioning this in the documentation.

Delay opening of page

I am trying to use djax combined with css3 to animate a page load and transition. I have used the following function to add classes to all the elements I want for the transition:

function pageTransition(direction) {
direction = direction == "in" ? direction : "out";
$('div, img').each(function () {
var $item = $(this);
setTimeout(function () {
$item.addClass('slide-' + direction)
}, 80 * Math.floor((Math.random() * 5) + 1));
});
}

Then I have a css keyframe animation for the entrance and exit transition. The intro works perfect but the exit doesn't. I call the exit to run in the following way:

$(window).bind('djaxClick', function (e, data) {
// Transition content out
pageTransition('out');
});

It all works fine as in the transition works but the problem I have is the function is called, the css animation starts but the next page opens before the css animation can complete or even start. I have tried everything I can think of but I just can't get this to work.

If anyone can think of anything or point me in the right direction I would greatly appreciate it!!!

Thanks in advance!

Make loaded page result available

As well as the URL and title from the loaded page, is it possible to make the whole result available to djaxLoad too?

For the WordPress theme I'm using (Genesis child theme), the layout between, say, content-sidebar and sidebar-content is done purely via the body class, so while djax is correctly loading the contents of #content and #sidebar, it's not displaying the sidebar in the right place, as the body class is for the original page.

I imagine other themes or pages might want the body ID, the html class / ID, or some other part too, so making the whole new page markup available within the data for djaxLoad means they can pick out which parts they need and update the new page accordingly.

Allow inline css and script tags to be updated.

Firstly I want to say this is a great plugin and I hope to be able to use it often, the only problem I have is my sites have a lot of inline JS (jquery, ajax, etc) and the JS is different on each page. When I move page, everything else updates except the inline JS which is removed, but not replaced with the new pages content. I even tried putting it in a div tag with no luck.

I there something I am missing, or is it just not supported?

How do I use djax with this page?

I'm trying to understand how djax works. I made two pages to test djax with, and it seems to work correctly, except for the div blocks. When I click a link, the djax element disappears, but the replacement does not appear.

Page 1 (index.php):

<html>
    <head>
        <script src="https://code.jquery.com/jquery.js"></script>
        <script src="jquery.djax.js"></script>
        <script type="text/javascript">
            jQuery(document).ready(function($) {
                $('body').djax('.djax');
            });
        </script>
        <title>Page1</title>
    </head>
    <body>
        <div class="container" id="music-player">
            <!-- This is just a visual element so I can see if the page reloads. -->
            <iframe width="400" height="110" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/playlists/23524797&amp;color=ff5500&amp;auto_play=false&amp;hide_related=false&amp;show_artwork=true"></iframe>
        </div>

        <a href="page2.php">Page 2!</a>
        <a href="index.php">Page 1</a>

        <div class="djax">
            <!-- Dynamic content -->
            Stuff1!
        </div>
    </body>
</html>

Page2 (page2.php):

<html>
    <head>
        <script src="https://code.jquery.com/jquery.js"></script>
        <script src="jquery.djax.js"></script>
        <script type="text/javascript">
            jQuery(document).ready(function($) {
                $('body').djax('.djax');
            });
        </script>
        <title>Page2</title>
    </head>
    <body>
        <div class="container" id="music-player">
            <!-- This is just a visual element so I can see if the page reloads. -->
            <iframe width="400" height="110" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/playlists/23524797&amp;color=ff5500&amp;auto_play=false&amp;hide_related=false&amp;show_artwork=true"></iframe>
        </div>

        <a href="page2.php">Page 2!</a>
        <a href="index.php">Page 1</a>

        <div class="djax">
            <!-- Dynamic content -->
            Stuff2!
        </div>
    </body>
</html>

The page loads fine from the start. When I click a link, the url and the title changes, but the <div class="djax"> just disappears.

Load Script an CSS

Hello.

I have found your jQuery Plugin and would use it in a TYPO3 Website.
My problem is, when i starts with the startpage and go to the contactform, the needed CSS and JS files are not loaded. So i wrote some code to load this files dynamically.

Maybe this code is interesting for you.

[code]

window.includes = { script: {}, css: {}};

function includesRemember() {
jQuery(document).find('script').each(function(index, element) {
var src = $(element).attr('src');
window.includes.script[src] = 1
});
jQuery(document).find('link[rel="stylesheet"]').each(function(index, element) {
var href = $(element).attr('href');
var media = $(element).attr('media');
window.includes.css[href+'-'+media] = 1
});
}

function includesUpdate(data) {
jQuery(data.response).filter('script').each(function(index, element) {
var src = $(element).attr('src');
if(!window.includes.script[src])
{
includesAppendScript(src);
window.includes.script[src] = 1
}
});
jQuery(data.response).filter('link[rel="stylesheet"]').each(function(index, element) {
var href = $(element).attr('href');
var media = $(element).attr('media');
if(!window.includes.css[href+'-'+media])
{
includesAppendCss(href, media);
window.includes.css[href+'-'+media] = 1
}
});
}

function includesAppendScript(filename){
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
document.getElementsByTagName("head")[0].appendChild(fileref)
}

function includesAppendCss(filename, media){
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("media", media)
fileref.setAttribute("href", filename)
document.getElementsByTagName("head")[0].appendChild(fileref)
}

$(window).bind('djaxLoad', function(e, data) {
includesUpdate(data);
}
[/code]

includesRemember is called after djax is inited.

Best regards
Reindl Bernd

Auto Update HTML Head Elements

Would be a good feature to have djax update all HTML Head Elements after ajaxing a new page.

title element
meta description
meta keywords ( optional )
body class
Pjax does this out the box and I would assume this would as well. with exception to changing body class

Callbacks / Deferred callbacks?

It'd be really nice if this plugin had callbacks.

I know we can bind to the $(window) for djaxLoad events and djaxClick events, but i don't necessarily want the new content injected into the DOM before i've decided what i want to do with it.

How would i go about exposing the callbacks?

live() is deprecated

Since jQuery 1.7, the live() function has been deprecated in favour of on().

Could the djax code be updated to use on()?

Extension .PHP is possible?

I can not put pages with extension .PHP to run, but it would be possible?
My English is a little rusty, sorry.

Compatibility with internet explorer?

Hi,

I have no success when running in Internet Explorer?
Djax is compatible with IE?
What is the logic to execute it perfectly?

Nice work, congratulations ..
Thank you for your attention.
I do not speak English very well.

jQuery v3.1.1 Compatibility issue SOLVED

I know djax is old and more thank likely not being supported but for what it is worth, for any other newbie out there like me, this seems to be working fine with the latest jQuery v3.1.1 with a small change.

You will need to change ".error" to ".fail" on line 212 (two hundred twelve) of the jquery.djax.js file. If you don't the console will give an error, stating that "Unexpected Token... .error is not a function..."

For some reason the jQuery Migration Plugin does not seem to be working for me... but reading through the warnings list I was able to figure out how to solve the issue.

Taken from the jQuery Migration Guide found at
https://github.com/jquery/jquery-migrate/blob/master/warnings.md

To Beezee - Thank you!! for creating and sharing this. Also, if you have advice that I should use another solution I'm all ears... I looked into PJAX, DDJAX, TurboLinks, AngularJS (too much for my needs) etc. - djax seemed the easiest to implement. If there is a more current fork/branch of this please advise. Thanks in Advance for any help or guidance you may provide.

Bind unique links or something?

Hello Beezee,

First of all, thank you a lot for this lil' plugin.

Secondly, I have an issue with it.

Indeed, I'd like to say to djax to only bind (then change via ajax method) only links on a DOM elements.

Let me clear this out if that's not (French guy, poor english here) :

I have:

<div class="menu">
<a class="menu__item menu--homepage" href="{URL homepage Site}">Go back to the homepage</a>
<ul class="menu__item">
<li><a href="{URL Portfolio}">Portfolio me</a></li>
<li><a href="{URL Contact}">Contact me</a></li>
</ul>
</div>

How can I say to djax to only bind the links from ul.menu__item but NOT a.menu--homepage ? Because I have an other template for my homepage and I don't want it to be loaded via djax.

Oh and I'm working with WordPress here.

Thank you for your concern.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.