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 YELLOW = [1.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=[
             CP1, CP2, CP3, CP4,  //front
	     CP1, CP5, CP8, CP4,  // left
	     CP3, CP7, CP8,       //top
	     CP5, CP6, CP7,       // back
	     CP3, CP2, CP6,       //right
	     CP5, CP1,             // go home
             YELLOW, RED, RED, RED,
             YELLOW, GREEN, GREEN, RED,
             RED, GREEN, GREEN,
             GREEN, GREEN, GREEN,
             RED, RED, GREEN,
             GREEN, YELLOW

           ];

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=[ TP1, TP2, TP3,     TP1, TP2, TP4,
            TP2, TP3, TP4,     TP3, TP1, TP4,

              RED, RED, RED,
            RED, RED, GREEN,
            RED, RED, GREEN,
            RED, RED, GREEN

            ];

function MakeItems() {
    let cube  = new Widget(canvas.GL(), canvas.Program(), 
                           "vPosition", "vColor", CUBE);
    let tet  = new Widget(canvas.GL(), canvas.Program(),
                            "vPosition", "vColor", TET);
    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, edges) {
        this.visible = true;
	this.size = edges.length/2;
	this.SetupVBO(gl,edges);

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

    SetupVBO(gl, edges) {
        this.vbuf =  gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, this.vbuf);

        gl.enableVertexAttribArray(this.vpos);

	gl.bufferData(gl.ARRAY_BUFFER,flatten(edges),gl.STATIC_DRAW);
    }

    Show() {
        this.visible = true;
    }

    Hide() {
        this.visible = false;
    }

    Visible() {
        return this.visible;
    }

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

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

              gl.vertexAttribPointer(this.cpos, 3, gl.FLOAT,
                                                   false, 0, this.size*12);
              gl.enableVertexAttribArray(this.cpos);

              gl.drawArrays(gl.LINE_LOOP, 0, this.size);
	  }
    }
}