<body>
  <form id="myform" method="post" action="server.php">
  <fieldset>
     <legend>Szukaj</legend>
     <input
      name="search"
      id="search"
      type="text"
    />
    <input type="submit" />
    </fieldset>
  </form>
  <script src="behaviors.js"></script>
</body>

---

// inicjowanie
myevent.addListener('myform', 'submit', function(e){
  // nie ma potrzeby propagacji zdarzenia
  e = myevent.getEvent(e);
  myevent.stopPropagation(e);
  // walidacja
  var el = document.getElementById('search');
  if (!el.value) { // niestety, pole jest puste
    myevent.preventDefault(e); // powstrzymaj wysyłanie formularza
    alert('Proszę wprowadzić zapytanie.');
  }
});

---

<head>
<script>
(function () {
  var s = document.createElement('script');
  s.src = 'behaviors.js';
  document.getElementsByTagName('head')[0].appendChild(s);
}());
</script>
</head>

---

MYAPP.event = {
  addListener: function(el, type, fn) {
    // ... ciało metody
  },
  removeListener: function(el, type, fn) {
    // ...
  },
  getEvent: function(e) {
    // ...
  }
  // ... inne właściwości i metody
};

---

MYAPP.dom = {};
MYAPP.dom.Element = function(type, properties){
  var tmp = document.createElement(type);
  for (var i in properties) {
    if (properties.hasOwnProperty(i)) {
      tmp.setAttribute(i, properties[i]);
    }
  }
  return tmp;
};

---

var link = new MYAPP.dom.Element('a', {href:'http://phpied.com', target: '_blank'});
var text = new MYAPP.dom.Text('Kliknij mnie!');
link.appendChild(text);
document.body.appendChild(link);

---

var MYAPP = {};
MYAPP.namespace = function (name) {
  var parts = name.split('.');
  var current = MYAPP;
  for (var i = 0; i < parts.length; i++) {
    if (!current[parts[i]]) {
      current[parts[i]] = {};
    }
    current = current[parts[i]];
  }
};

---

if (window.addEventListener) {
  MYAPP.event.addListener = function (el, type, fn) {
    el.addEventListener(type, fn, false);
  };
  MYAPP.event.removeListener = function (el, type, fn) {
    el.removeEventListener(type, fn, false);
  };
} else if (document.attachEvent) { // IE
  MYAPP.event.addListener = function (el, type, fn) {
    el.attachEvent('on' + type, fn);
  };
  MYAPP.event.removeListener = function (el, type, fn) {
    el.detachEvent('on' + type, fn);
  };
} else { // starsze przeglądarki
  MYAPP.event.addListener = function (el, type, fn) {
    el['on' + type] = fn;
  };
  MYAPP.event.removeListener = function (el, type) {
    el['on' + type] = null;
  };
}

---

var MYAPP = {};
MYAPP.myevent = {
  addListener: function (el, type, fn) {
    if (el.addEventListener) {
      MYAPP.myevent.addListener = function (el, type, fn) {
        el.addEventListener(type, fn, false);
      };
    } else if (el.attachEvent) {
      MYAPP.myevent.addListener = function (el, type, fn) {
        el.attachEvent('on' + type, fn);
      };
    } else {
      MYAPP.myevent.addListener = function (el, type, fn) {
        el['on' + type] = fn;
      };
    }
    MYAPP.myevent.addListener(el, type, fn);
  }
};

---

MYAPP.dom.FancyButton = function (text, type) {
  var b = document.createElement('input');
  b.type = type || 'submit';
  b.value = text;
  return b;
};

---

var MYAPP = {};
MYAPP.dom = {};
MYAPP.dom.FancyButton = function (text, conf) {
  var styles = {
    font: 'Verdana',
    border: '1px solid black',
    color: 'black',
    background: 'grey'
  };
  function setStyles(b) {
    var i;
    for (i in styles) {
      if (styles.hasOwnProperty(i)) {
        b.style[i] = conf[i] || styles[i];
      }
    }
  }
  conf = conf || {};
  var b = document.createElement('input');
  b.type = conf.type || 'submit';
  b.value = text;
  setStyles(b);
  return b;
};

---

var MYAPP = {};
MYAPP.dom = (function(){
  var _setStyle = function(el, prop, value) {
    console.log('setStyle');
  };
  var _getStyle = function(el, prop) {
    console.log('getStyle');
  };
  return {
    setStyle: _setStyle,
    getStyle: _getStyle,
    yetAnother: _setStyle
  };
}());

---

var MYAPP = {};
MYAPP.dom = (function(){
  // kod inicjujący
  function _private(){
    // ... ciało
  }
  return {
    getStyle: function(el, prop) {
      console.log('getStyle');
      _private();
    },
    setStyle: function(el, prop, value) {
      console.log('setStyle');
    }
  };
}());

---

namespace('MYAPP.module.amazing');

MYAPP.module.amazing = (function () {

  // krótkie nazwy dla zależności
  var another = MYAPP.module.another;

  // lokalne (prywatne) zmienne
  var i, j;

  // prywatne funkcje
  function hidden() {}

  // publiczny API
  return {
    hi: function () {
      return "witaj";
    }
  };
}());

---

var obj = new MYAPP.dom.Element('span');
obj.setText('witaj');
obj.setStyle('color', 'red');
obj.setStyle('font', 'Verdana');
document.body.appendChild(obj);

---

document.body.appendChild(
  new MYAPP.dom.Element('span')
    .setText('witaj')
    .setStyle('color', 'red')
    .setStyle('font', 'Verdana')
);

---

<?xml version="1.1" encoding="iso-8859-1"?>
<response>
  <name>Stoyan</name>
  <family>Stefanov</family>
  <books>
    <book>OOJS</book>
    <book>JSPatterns</book>
    <book>JS4PHP</book>
  </books>
</response>

---

function Logger() {
  if (typeof global_log === "undefined") {
    global_log = this;
  }
  return global_log;
}

---

function Logger() {
  if (!Logger.single_instance) {
    Logger.single_instance = this;
  }
  return Logger.single_instance;
}

---

var MYAPP = {};
MYAPP.dom = {};
MYAPP.dom.Text = function (url) {
  this.url = url;
  this.insert = function (where) {
    var txt = document.createTextNode(this.url);
    where.appendChild(txt);
  };
};
MYAPP.dom.Link = function (url) {
  this.url = url;
  this.insert = function (where) {
    var link = document.createElement('a');
    link.href = this.url;
    link.appendChild(document.createTextNode(this.url));
    where.appendChild(link);
  };
};
MYAPP.dom.Image = function (url) {
  this.url = url;
  this.insert = function (where) {
    var im = document.createElement('img');
    im.src = this.url;
    where.appendChild(im);
  };
};

---

var url = 'http://www.phpied.com/images/covers/oojs.jpg';

var o = new MYAPP.dom.Image(url);
o.insert(document.body);

var o = new MYAPP.dom.Text(url);
o.insert(document.body);

var o = new MYAPP.dom.Link(url);
o.insert(document.body);

---

var o;
if (type === 'Image') {
  o = new MYAPP.dom.Image(url);
}
if (type === 'Link') {
  o = new MYAPP.dom.Link(url);
}
if (type === 'Text') {
  o = new MYAPP.dom.Text(url);
}
o.url = 'http://...';
o.insert();

---

var obj = {
  doSomething: function () {
    console.log('tak jest, już się robi');
  }
  // ...
};
obj = obj.getDecorator('deco1');
obj = obj.getDecorator('deco13');
obj = obj.getDecorator('deco5');
obj.doSomething();

---

tree.RedBalls = function () {
  this.decorate = function () {
    this.RedBalls.prototype.decorate();
    alert('Powieś kilka czerwonych bombek');
  };
};
tree.BlueBalls = function () {
  this.decorate = function () {
    this.BlueBalls.prototype.decorate();
    alert('Dodaj niebieskie bombki');
  };
};
tree.Angel = function () {
  this.decorate = function () {
    this.Angel.prototype.decorate();
    alert('Gwiazda na czubku');
  };
};
---

var observer = {
  addSubscriber: function (callback) {
    if (typeof callback === "function") {
      this.subscribers[this.subscribers.length] = callback;
    }
  },
  removeSubscriber: function (callback) {
    for (var i = 0; i < this.subscribers.length; i++) {
      if (this.subscribers[i] === callback) {
        delete this.subscribers[i];
      }
    }
  },
  publish: function (what) {
    for (var i = 0; i < this.subscribers.length; i++) {
      if (typeof this.subscribers[i] === 'function') {
        this.subscribers[i](what);
      }
    }
  },
  make: function (o) { // zamienia obiekt w obiekt obserwowany
    for (var i in this) {
      if (this.hasOwnProperty(i)) {
        o[i] = this[i];
        o.subscribers = [];
      }
    }
  }
};
---

var blogger = {
  writeBlogpost: function() {
    var content = 'Dzisiaj jest ' + new Date();
    this.publish(content);
  }
};
---

var jack = {
  read: function(what) {
    console.log('Przeczytałem właśnie, że ' + what)
  }
};
var jill = {
  gossip: function(what) {
    console.log('Nie mów nikomu, że ci powiedziałem, ale ' + what)
  }
};

---

