function WSTab(args){
  var self = this;
  var storageKey = String(args.storageKey);
  this.storageKey = storageKey;
  var wind = new StandardWindow({
    color: args.color || "orange",
  });
  this.asterisk = span('*');
  this.asterisk.e.style.display = 'none';
  wind.title = args.title || "Untitled";
  wind.toolbar.left.append(new Button({
    className: ( args.color2 ? args.color2 : 'orange' ) + ' quiet',
    caption: 'Save',
    action: function(){
      self.save();
    },
  }));
  wind.on('keydown', function(e){
    if(e.keyCode === 83 && e.ctrlKey){
      self.save();
      e.stopPropagation();
      e.preventDefault();
    }
  });
  var cm = CodeMirror(wind.body.e, {
    mode: args.mode || '',
    indentWithTabs: false,
    tabSize: 2,
    lineNumbers: true,
    autoRefresh:true,
    theme: 'neat',
  });
  cm.getWrapperElement().classList.add('full-element');
  wind.on('activated', function(){
    cm.refresh();
  });

  chrome.storage.sync.get(storageKey, function(data){
    if(data[storageKey] !== undefined){
      cm.setValue(String(data[storageKey]));
    }
    else{
      cm.setValue('');
    }
    cm.on('change', function(e){
      wind.tabViewHandle.e.style.fontWeight = 900;
      self.asterisk.e.style.display = null;
    });
    cm.refresh();
  });

  this.main = wind;
  this.cm = cm;
  if(args.tabs instanceof Element){
    args.tabs.append(wind);
    wind.tabViewHandle.append(this.asterisk);
  }
}

WSTab.prototype.save = function(){
  var self = this;
  var value = this.cm.getValue();
  var obj = {};
  obj[this.storageKey] = value;
  chrome.storage.sync.set(obj, function(){
    self.main.tabViewHandle.e.style.fontWeight = null;
    self.asterisk.e.style.display = 'none';
  });
}

var main = new StandardWindow({
  color: "white",
});
main.addClass('full-window');

var tabs = new TabView();
main.append(tabs);

var hostname = window.location.hash;
var cssKey = "CSS_"+hostname;
var jsKey = "js_"+hostname;

title = span(hostname.slice(1));
title.e.style.fontSize = "25px";
main.toolbar.append(title);

var cssTab = new WSTab({
  color: "blue",
  color2: "white",
  title: "CSS",
  tabs: tabs,
  mode: "css",
  storageKey: 'CSS_'+hostname,
});

var jsTab = new WSTab({
  color: "yellow",
  color2: "black",
  title: "JavaScript",
  tabs: tabs,
  mode: "javascript",
  storageKey: "js_"+hostname,
});

document.body.appendChild(main.e);

@@ -1072,22 +1072,72 @@
 Key%5D));%0A
+      self.savedValue = String(data%5BstorageKey%5D);%0A
     %7D%0A
-
     else
@@ -1161,16 +1161,44 @@
 ue('');%0A
+      self.savedValue = '';%0A
     %7D%0A  
@@ -1224,24 +1224,71 @@
 unction(e)%7B%0A
+      if(self.savedValue !== cm.getValue())%7B%0A  
       wind.t
@@ -1328,24 +1328,26 @@
  900;%0A      
+  
 self.asteris
@@ -1368,24 +1368,159 @@
 lay = null;%0A
+      %7D%0A      else%7B%0A        self.main.tabViewHandle.e.style.fontWeight = null;%0A        self.asterisk.e.style.display = 'none';%0A      %7D%0A
     %7D);%0A    
@@ -1797,16 +1797,16 @@
 j = %7B%7D;%0A
-
   obj%5Bth
@@ -1829,16 +1829,43 @@
  value;%0A
+  this.savedValue = value;%0A
   chrome

Make unsaved changes indicator disappear when recipe value equals saved one