<repo_name>kustomzone/WebExpress<file_sep>/js/materialdesign/ripple.js
var Ripple = class Ripple {
    static makeRipple(element, xpos, ypos, height, width, time, fadeoutopacity) {
        var $rippleElement = $('<span class="ripple-effect" />'),
            $buttonElement = element,
            btnOffset = $buttonElement.offset(),
            xPos = xpos,
            yPos = ypos,
            size = parseInt(Math.min(height, width) * 0.5),
            animateSize = parseInt(Math.max(width, height) * Math.PI);
        $rippleElement
            .css({
                top: yPos,
                left: xPos,
                width: size,
                height: size,
                backgroundColor: $buttonElement.data("ripple-color")
            })
            .appendTo($buttonElement)
            .animate({
                width: animateSize,
                height: animateSize,
                opacity: fadeoutopacity
            }, time, 'linear', function () {
                $(this).remove();
            });
    }
};
<file_sep>/js/applets/history.js
function isInArray(value, array) {
    return array.indexOf(value) > -1;
}
var obj = getHistoryData();
var groups = [];
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth() + 1;
var yyyy = today.getFullYear();
var count = 0;
var headers = [];
if (dd < 10) {
    dd = '0' + dd;
}

if (mm < 10) {
    mm = '0' + mm;
}
today = mm + '-' + dd + '-' + yyyy;
var checkboxes = [];
obj.history = obj.history.reverse();
var checkedCount = 0;
$('#unselect-btn').click(function() {
    $('.checkbox').each(function(i) {
        if (this.checked) {
            this.checked = false;
            checkedCount -= 1;
            verifyCheckboxes();
        }
    });
});
$('.icon-button').mousedown(function() {
     Ripple.makeRipple($(this), 10, 10, 15, 15, 300, 0);
});
$('#delete-btn').click(function() {
   
    $('.checkbox').each(function(i) {
        if (this.checked) {
            console.log(obj.history[this.id]);
            
            for (var i = 0; i < obj.history.length; i++) {
                if (obj.history[i].id == this.id) {
                    obj.history.splice(i, 1);
                }
            }
            this.item.remove();
            if (this.item.length <= 0) {
                checkedCount = 0;
                verifyCheckboxes(); 
            }
            checkedCount = 0;
            this.group.items -= 1;
            if (this.group.items <= 0) {
                this.group.remove();
                headers.splice(headers.indexOf(this.group), 1);
                headers[0].css('margin-top', '-32px');
            }
            verifyCheckboxes();
        }
    });
    obj.history.sort(function(a, b) {
        return parseFloat(a.id) - parseFloat(b.id);
    });
    saveHistory("");
    saveHistory(JSON.stringify(obj));
});
$('.flat-button').mousedown(function(e) {
    var relX = e.pageX - $(this).offset().left;
    var relY = e.pageY - $(this).offset().top;
    Ripple.makeRipple($(this), relX, relY, $(this).width() + 16, $(this).height() + 16, 300, 0);
});
function verifyCheckboxes() {
    $('#selected-items').html('Selected items: ' + checkedCount);
    if (checkedCount >= 1) {
        $(".toolbar").animate({backgroundColor: '#00BCD4'}, {duration: 200, queue: false});
        $('.default-toolbar').css('visibility', 'hidden');
        $('.selecteditems-toolbar').css('visibility', 'visible');
    } else {
        $(".toolbar").animate({backgroundColor: '#3F51B5'}, {duration: 200, queue: false});
        $('.default-toolbar').css('visibility', 'visible');
        $('.selecteditems-toolbar').css('visibility', 'hidden');
    }
}
for (var i = 0; i < obj.history.length; i++) {
    var jsonItem = obj.history[i];

    function additem(header) {
        var item = $('<div class="item" style="margin-bottom: -8px; ">').appendTo('.card');
        var checkbox = $('<div class="checkbox ripple-icon" data-ripple-color="#444" style="display: inline-block;"></div>').appendTo(item);
        checkbox[0].item = item;
        if (header != null)
        checkbox[0].group = header;
        checkbox[0].id = jsonItem.id;
        checkbox.click(function(e) {
            if (this.checked) {
                checkedCount += 1;
            } else {
                checkedCount -= 1;
            }
            verifyCheckboxes();
        });
        checkboxes.push(checkbox[0])
        var hour = $('<p style="display: inline-block;margin-left: 16px; width: 50px;color: #9E9E9E;position: relative; top: -4px;">' + jsonItem.time + '</p>').appendTo(item);
        var title = $('<p style="margin-left: 52px;display: inline-block;white-space: nowrap;overflow:hidden !important;text-overflow: ellipsis;max-width: 40%;max-height: 16px; position: relative; top: 14px; margin-top: -4px;">' + jsonItem.title + '</p>').appendTo(item);
        var link = $('<a href="' + jsonItem.link + '" style="margin-left: 16px; display: inline-block;white-space: nowrap;overflow:hidden !important;text-overflow: ellipsis;max-width: 30%; max-height: 16px; margin-top: -4px;">' + jsonItem.link + '</a>').appendTo(item);
        count += 1;
    }
    var currentHeader;
    if (!isInArray(jsonItem.date, groups)) {
        var cardHeader;
        if (groups.length == 0) {
            if (jsonItem.date == today) {
                cardHeader = $('<div class="card-header" style="margin-bottom:32px;"><div style="padding-bottom: 16px;">Today</div></div>').appendTo('.card');
            } else {
                cardHeader = $('<div class="card-header" style="margin-bottom:32px;"><div style="padding-bottom: 16px;">' + jsonItem.date + '</div></div>').appendTo('.card');
            }
        } else {
            cardHeader = $('<div class="card-header" style="margin-top: 32px; margin-bottom:32px;"><div style="padding-bottom: 16px;">' + jsonItem.date + '</div></div>').appendTo('.card');
        }
        var hr = $('<hr style="position: absolute; top: 0; left:0;right:0; margin-top: 0; padding-top: 0;" />').appendTo(cardHeader);
        var hr = $('<hr style="position: absolute; bottom: 0; left:0;right:0; margin-bottom: 0; padding-bottom: 0;" />').appendTo(cardHeader);
        cardHeader.items = 1;
        additem(cardHeader);
        currentHeader = cardHeader;
        groups.push(jsonItem.date);
        headers.push(cardHeader);
    } else {
        currentHeader.items += 1;
        additem(currentHeader);
        
    }
}
<file_sep>/js/extensions/preload.js
var fs = require('fs');
var os = require('os');
const {app} = require('electron').remote;

var historyPath = app.getPath('userData') + '/userdata/history.json';
var extensionsPath = app.getPath('userData') + '/userdata/extensions';
var userdataPath = app.getPath('userData') + '/userdata';

global.getHistoryData = function () {
    return JSON.parse(fs.readFileSync(historyPath));
}

global.saveHistory = function (json) {
    fs.writeFile(historyPath, json, function (err) {
        if (err) {
            return console.log(err);
        }
    });
}

<file_sep>/js/main.js
const remote = require('electron').remote;
const {app} = require('electron').remote;
var os = require('os');

var historyPath = app.getPath('userData') + '/userdata/history.json';
var extensionsPath = app.getPath('userData').replace(/\\/g, '/') + '/userdata/extensions';
console.log(extensionsPath);
var userdataPath = app.getPath('userData') + '/userdata';

var mainWindow = remote.getCurrentWindow();
var fs = require('fs');
var IsThere = require("is-there");
var dir = require('node-dir');

$(document).ready(function () {
    var tab = new Tab();
    addTab(new TabWindow(tab, "webexpress://newtab"), tab);
});
window.onresize = function (event) {
    calcSizes(false, false);
};

$('.windowbutton-close').click(function () {
    mainWindow.close();
});
$('.windowbutton-maximize').click(function () {
    if (mainWindow.isMaximized()) {
        mainWindow.unmaximize();
    } else {
        mainWindow.maximize();
    }

});
$('.windowbutton-minimize').click(function () {
    mainWindow.minimize();
});



function checkFiles() {
    //check if directory called userdata exists
    if (!IsThere(userdataPath)) {
        fs.mkdir(userdataPath);
    }
    //check if directory called extensions exists
    if (!IsThere(extensionsPath)) {
        fs.mkdir(extensionsPath);
    }
    //check if file called history.json exists
    if (!IsThere(historyPath)) {
        fs.writeFile(historyPath, '{"history":[]}');
    }
}

/*function loadThemes() {
    if (jFileType == "stylesheet" || jFileType == "css") {
        $('head').append('<link rel="stylesheet" type="text/css" href="' + jFileUrl + '">')
    }
} TODO */
<file_sep>/README.md
# WebExpress
(readme work in progress)
* authors: <NAME> (Sential)
* other contributors: <NAME> (xNerhu22)

#Features
* Colored tabs
* Settings `TODO`
* History
* Context menu
* Suggestions
* Bookmarks `TODO`
* Downloads `TODO`
* Developer tools
* Screenshot `TODO`
* Private mode `TODO`
* Extensions (work in progress)
* Beautiful UI (material design)

#Getting source code
You need to install node.js
### Starting
```
git clone https://github.com/Sential/WebExpress.git
npm install && npm start
```
### Building
```
npm run build
```

#Downloads
`TODO`:LINK

#Screenshots
`TODO`

#`TODO`
* Bookmarks
* Extensions
* New tab page
* keyboard shortcuts
* Other features like screenshots etc.
* Downloads
* Tutorial for extensions

#See bug or missing feature?
You can write on Issues page or create new pull request


<file_sep>/main.js
const electron = require('electron')
const protocol = electron.protocol
const app = electron.app
const path = require('path')
const BrowserWindow = electron.BrowserWindow
let mainWindow

function createWindow() {
    mainWindow = new BrowserWindow({
        width: 1024,
        height: 768,
        frame: false
    })
    mainWindow.loadURL(`file://${__dirname}/index.html`)
    mainWindow.webContents.openDevTools()
    mainWindow.on('closed', function() {
        mainWindow = null
    })
    mainWindow.setMenu(null)
    mainWindow.webContents.session.on('will-download', (event, item, webContents) => {
        item.setSavePath(item.getFilename()) //TODO set path to downloads folder
    })
}
protocol.registerStandardSchemes(['webexpress'])
app.on('ready', function() {
    protocol.registerFileProtocol('webexpress', (request, callback) => {
        var url = request.url.substr(13)
        var lastChar = url.substr(url.length - 1)
        var s = url.split("/");
        if (lastChar != "/") {
            url = url.replace(s[0], "")
        }
        if (lastChar == "/") {
            url = url.substring(0, url.length - 1)
            url += ".html"
        }
        callback({
            path: path.normalize(`${__dirname}/${url}`)
        })
    }, (error) => {
        if (error) console.error('Failed to register protocol')
    })
    createWindow();
});
app.on('window-all-closed', function() {
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

app.on('activate', function() {
    if (mainWindow === null) {
        createWindow()
    }
})
