Информация к новости
  • Просмотров: 770
  • Автор: sulicompany
  • Дата: 16-12-2012, 00:19
 (голосов: 0)
16-12-2012, 00:19

Создаем расширения для Google Chrome

Категория: Программирование » HTML


Принцип написания расширений

Некоторые думают, что расширение это нечто заморское, неподвластно простым людям. На самом деле для его написания достаточно просто блокнота, в котором это все писать, и браузера, в котором тестировать написаное.Итак, любое расширение для Chrome состоит из следующих составляющих:
  • Файл манифеста manifest.json, в котором записывается информация о приложении;
  • Иные файлы, которые используются в расширении: это могут быть html-странички, скрипты, картинки и т.д.
Для запуска готовой работы нужно всего лишь на  в режиме разработчика загрузить ваше творение.Итак, приступим к работе!

Пишем файл манифеста

Файл манифеста хранится в корневой папке проекта и, как вы уже поняли, представляет из себя набор данных в формате JSON. Рассмотрим исхоник манифеста, а после этого я опишу каждый пункт подробнее.
{
    "name": "Profile Guard",
    "description": "Google Chrome profile protection by password",
    "version": "0.1",
    "permissions": [ "tabs" ],
    "background_page": "background.html",
    "icons": {
        "48":"images/bigicon.jpg"
    },
    "browser_action": {
        "default_title": "Profile Guard",
        "default_icon": "images/icon.png",
        "popup": "popup.html"
    }
}
А теперь по порядку:
  • namedescription и version — собственно имя расширения, его короткое описание и номер версии;
  • permissions — массив с дополнительными правами расширения на выполнение тех или иных действий. Подробнее почитать можно . В даном случае расширение может знать об открытых вкладках и окнах браузера;
  • background_page — главная страника которая запускается при запуске браузера и работает на фоне;
  • icons — набор иконок разных размеров;
  • browser_action — описание кнопочки на панели инструментов. default_title — текст при наведении на кнопку, default_icon — иконка на кнопке, popup — html-страничка, которая откроется в попапе после клика;
Кроме этих параметров в файле манифеста может быть и много других.

Фоновая страничка

Фоновая страничка будет проверять установлен ли пароль и запрашивать его при открытии браузера или создании окна с неким профилем. От протестированных мною расширений моё отличается именно тем, что более менее адекватно работает в режиме мультипрофильности.Пароль от нашего профиля будет храниться в localStorage['profile_password']. localStorage — это массив, в котором расширение может хранить свои какие-то данные, не беспокоясь о том, что какое-то другое расширение доступиться к этим данным. Для каждого расширения и профиля это отдельная переменная, поэтому можно устанавливать разные пароли на разные профили.
<html>
<head>
<title>Profile Guard background page</title>
</head>
<body onload="pass();">
<script type="text/javascript">
function pass(){
    chrome.windows.getAll(function(wins){
        if(wins.length==1){
            if(localStorage["profile_password"]){
                var pass = prompt("Please enter password:","");
                if(pass!=localStorage["profile_password"]){
                    alert("Access denied!");
                    chrome.windows.getCurrent(function (window){chrome.windows.remove(window.id)});
                }
            }
        }
    });
}
chrome.windows.onCreated.addListener(function(window){
    pass();
});
</script>
</body>
</html>

Установка и изменение пароля

Устанавливать и изменять пароль мы сможем на страничке, которая открывается в попапе popup.html. Изначально пароль не установлен и его можно будет установить. Пожже его можно будет изменить или вовсе удалить. Короче говоря всяческие манипуляции с паролем для входа.Исходник файла запихиваю в спойлер, особо пояснять ничего не буду, по-моему и так всё понятно.
файл popup.html
<html>
<head>
<title>Profile Guard background page</title>
<style>
body {
    font-family: sans-serif;
    background: #f5f5f5;
    color: #666E79;
    width: 250px;
}
div.form {
    background: white;
    border: solid 1px #e8e8e8;
    border-radius: 5px;
}
h1 {
    margin:0;
    padding: 0;
    font-size: 20px;
    text-align: center;
    line-height: 40px;
}
h2 {
    margin: 0 10px;
    padding: 0;
    font-size: 14px;
    line-height: 30px;
}
button {
    border:solid 1px #5E697C;
    background: URL(images/button.jpg);
    color: white;
    font-size: 13px;
    line-height: 22px;
    margin: 10px auto 15px;
    display: block;
    border-radius: 4px;
    cursor: pointer;
    font-weight: bolder;
    text-shadow: rgba(0,0,0,0.2) -1px -1px 0px;
    padding: 1 10px;
}
button:hover {
    background: URL(images/hover.jpg);
}
.newbutton {
    margin: 15px 0;
}
.field {
    padding: 5px 15px;
    text-align:right;
}
label {
    color: #989898;
    font-weight: bolder;
    font-size: 12px;
    float:left;
    line-height: 25px;
}
input {
    width: 135px;
    text-align:left;
}
</style>
<script>
    function view(){
        if(!localStorage["profile_password"]){
            elnewbutton.style.display = "block";
            elnewpass.style.display = "none";
            elchpass.style.display = "none";
        } else {
            elnewbutton.style.display = "none";
            elnewpass.style.display = "none";
            elchpass.style.display = "block";
        }
    }
    function newpass(){
        if(!localStorage["profile_password"]){
            elnewpass.style.display = "block";
            elnewbutton.style.display = "none";
        }
    }
    function newset(){
        if(!localStorage["profile_password"]){
            var pass = npass.value;
            var conf = nconf.value;
            if(pass){
                if(pass!=conf){
                    alert("Passwords don't match!");
                    npass.value = "";
                    nconf.value = "";
                } else {
                    localStorage["profile_password"] = pass;
                    view();
                    alert("Password successfully changed");
                }
            }
        }
    }
    function chset(){
        if(localStorage["profile_password"]){
            var old = cold.value;
            var pass = cpass.value;
            var conf = cconf.value;
            if(old!=localStorage["profile_password"]){
                alert("Old password is entered incorrectly");
                cold.value = "";
            } else {
                if(pass){
                    if(pass!=conf){
                        cpass.value = "";
                        cconf.value = "";
                        alert("Passwords do not match!");
                    } else {
                        localStorage["profile_password"] = pass;
                        view();
                        alert("Password successfully changed");
                    }
                }
            }
        }
    }
    function claerpass(){
        if(localStorage["profile_password"]){
            var old = cold.value;
            if(!old){
                alert("Enter old password first!");
            } else {
                if(old!=localStorage["profile_password"]){
                    alert("Old password is entered incorrectly");
                    cold.value = "";
                } else {
                    localStorage["profile_password"] = "";
                    view();
                    alert("Password successfully deleted");
                }
            }
        }
    }
</script>
</head>
<body onload="view();">
<div class="form">
<h1>Profile Guard</h1>
</div>
<div class="newbutton" id="newbutton">
<button id="elnewbutton" onclick="newpass();">Set new password</button>
</div>
<div class="newpass form" id="elnewpass" style="display:block;">
<h2>Set password</h2>
<div class="field">
<label>Password</label>
<input type="password" id="npass" />
</div>
<div class="field">
<label>Confirm</label>
<input type="password" id="nconf" />
</div>
<button id="elnewset" onclick="newset();">Set new password</button>
</div>
<div class="newpass form" id="elchpass" style="display:block;">
<h2>Password change</h2>
<div class="field">
<label>Old password</label>
<input type="password" id="cold" />
</div>
<div class="field">
<label>Password</label>
<input type="password" id="cpass" />
</div>
<div class="field">
<label>Confirm</label>
<input type="password" id="cconf" />
</div>
<button id="elchset" onclick="chset();">Change password</button>
<button id="elclear" onclick="claerpass();">Delete password</button>
</div>
</body>
</html>

Завершающий этап

В завершение нам нужно упаковать наше творение, это можна сделать на странице расширений нажав на кнопку «Упаковка расширений». Указав папку с нашим расширением на выходе мы получаем два файла:.crx — файл с самим расширением, .rem — файл с секретным ключом. В придачу вы можете поделится своим творением с людьми, залив его на , но для этого нужно заплатить гуглу взнос в размере $5 (но это лишь первый раз, при регистрации).Прошу не судить строго, ведь это моё первое расширение. Скачать исходник можно . Уапкованное расширение не даю, так как в хроме можно устанавливать лишь расширения с Вебстора.
Пишите свои замечания и замеченные баги.