The HTML file:

<html>
<head>

<script id="vertex-shader" type="x-shader/x-vertex" >
attribute vec4 vPosition;
attribute vec4 vColor;

varying vec4 color;

void main() {
    float d = 0.2;

    // send the new color down the pipeline
    color = vColor;

    // translate matrix 
    mat4 translate = mat4(
                   vec4(1.0, 0.0, 0.0, 0.0),
                   vec4(0.0, 1.0, 0.0, 0.0),
                   vec4(0.0, 0.0, 1.0, 0.0),
                   vec4(0.0, 0.25, 0.75, 1.0));
                      
    // pinhole camera projection matrix.
    mat4 project = mat4(
                   vec4(1.0, 0.0, 0.0, 0.0),
		   vec4(0.0, 1.0, 0.0, 0.0),
		   vec4(0.0, 0.0, 0.0, 1.0/d),
		   vec4(0.0, 0.0, 0.0, 0.0));

    // apply the transformations
    gl_Position = project * translate *  vPosition;
}
</script>

<script id="fragment-shader" type="x-shader/x-fragment">
precision highp float;

varying vec4 color;

void main(){
   gl_FragColor = color;
}
</script>

<script type="text/javascript" src="../Common/webgl-utils.js"></script>
<script type="text/javascript" src="../Common/initShaders.js"></script>
<script type="text/javascript" src="../Common/MV.js"></script>

<script type="text/javascript" src="Widget.js"></script>
<script type="text/javascript" src="Program.js"></script>
<script type="text/javascript" src="GLCanvas.js"></script>

<body>
<script>
    'use strict'
    var canvas = new Canvas(500, 500,Keypress);
    var Objects = [];

    MakeItems();
    Display();
</script>
</body>

GLCanvas.js

'use strict'

class Canvas {
    constructor (width, height, Keypress) {
        this.height = height;
        this.width = width;

        this.MakeCanvas();
        this.canvas.addEventListener("keypress", Keypress);

        this.SetupGL();
        this.MakeShaders();

        this.Init();
    }

    MakeCanvas() {
        if (this.width == undefined || this.width < 0) {
           this.width = 300;
        }

        if (this.height == undefined || this.height < 0) {
           this.height = 300;
        }

         this.canvas = document.createElement('canvas')
	 this.canvas.tabIndex=0;
         this.canvas.height = this.height;
         this.canvas.width = this.width;
         this.canvas.style="border:1px solid #000000;"

         document.body.appendChild(this.canvas);
    }

    SetupGL() {
        this.gl = WebGLUtils.setupWebGL(this.canvas);
        if (!this.gl) {
            alert ("WebGL isn't available");
	    return;
        }
	this.gl.getExtension('OES_standard_derivatives');
    }

    MakeShaders() {
        this.program = initShaders(this.gl, "vertex-shader","fragment-shader");
        this.gl.useProgram(this.program);
    }

    Init() {
        this.gl.clearColor(1.0, 1.0, 1.0, 1.0);
        this.gl.viewport(0,0, this.width, this.height);
    }

    Program() {
       return this.program;
    }

    GL() {
       return this.gl;
    }

    Clear() {
        this.gl.clear(this.gl.COLOR_BUFFER_BIT);
    }
};

Program.js

'use strict'

const RED = [1.0, 0.0, 0.0]
const GREEN = [0.0, 1.0, 0.0]

const CP1 = [-0.5, -0.5, -0.5]
const CP2 = [ 0.5, -0.5, -0.5]
const CP3 = [ 0.5,  0.5, -0.5]
const CP4 = [-0.5,  0.5, -0.5]
const CP5 = [-0.5, -0.5,  0.5]
const CP6 = [ 0.5, -0.5,  0.5]
const CP7 = [ 0.5,  0.5,  0.5]
const CP8 = [-0.5,  0.5,  0.5]

const CUBE_POINTS = [CP1, RED, CP2, RED, CP3, RED, CP4, RED,
                     CP5, GREEN, CP6, GREEN,  CP7, GREEN, CP8, GREEN];

const CUBE_INDEX = [[0, 1, 2, 3], [4, 5, 6, 7], 
                    [2, 6, 7, 3], [1, 5, 4, 0], 
                    [0, 4, 7, 3], [1, 5, 6, 2]];

const TP1 = [-0.5, -0.5, -0.5]
const TP2 = [0.5, -0.5, -0.5]
const TP3 = [0.0, -0.5, 0.5]
const TP4 = [0.0, 0.5, 0.0]

const TET_POINTS = [TP1, RED, TP2, RED, TP3, RED, TP4, GREEN];

const TET_INDEX = [[0, 1, 2], [0, 1, 3], [2, 0, 3], [1, 2, 3]];

function MakeItems() {
    let cube  = new Widget(canvas.GL(), canvas.Program(), "vPosition", 
                     "vColor", CUBE_POINTS, CUBE_INDEX);
    let tet  = new Widget(canvas.GL(), canvas.Program(), "vPosition",
                      "vColor", TET_POINTS, TET_INDEX);
    tet.Hide();
    Objects.push(cube);
    Objects.push(tet);
}

function Keypress(evnt) {
    if (evnt.key >= '0' && evnt.key <= '9') {
        ToggleItemVis(evnt.key-'0');
    }

    Display();
}

function ToggleItemVis(id) {
    if (id < Objects.length) {
         if (Objects[id].Visible() ) {
	     Objects[id].Hide();
	 } else {
	     Objects[id].Show();
	 }
    }
}

function DisplayItem(item) {
    item.Display(canvas.GL());
}

function Display() {
    canvas.Clear();
    Objects.forEach(DisplayItem);
}

Widget.js

'use strict'

class Widget {
    constructor(gl, program, posName, colorName, points, index) {
        this.visible = true;

        this.faces = index.length;
        this.points = index[0].length;

	this.SetupVBO(gl, points, index);

	this.vpos =  gl.getAttribLocation(program, posName);
	this.cpos =  gl.getAttribLocation(program, colorName);
    }

    SetupVBO(gl, edges,index) {
        this.vbuf =  gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, this.vbuf);
	gl.bufferData(gl.ARRAY_BUFFER,flatten(edges),gl.STATIC_DRAW);

        this.ibuf = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.ibuf);
	gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
                          new Uint16Array(flatten(index)), gl.STATIC_DRAW);

    }

    Show() {
        this.visible = true;
    }

    Hide() {
        this.visible = false;
    }

    Visible() {
        return this.visible;
    }

    Display(gl) {
          let face;
          if (this.visible) {
              gl.bindBuffer(gl.ARRAY_BUFFER, this.vbuf);

              gl.vertexAttribPointer(this.vpos, 3, gl.FLOAT, false, 24, 0);
              gl.enableVertexAttribArray(this.vpos);

              gl.vertexAttribPointer(this.cpos, 3, gl.FLOAT, false, 24, 12);
              gl.enableVertexAttribArray(this.cpos);

              gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.ibuf);

              for(face = 0; face < this.faces; face++){
                   gl.drawElements(gl.LINE_LOOP, this.points, gl.UNSIGNED_SHORT,
                         face*this.points*2);
              }
	  }
    }
}