diff --git a/src/js/page.js b/src/js/page.js
new file mode 100644
index 0000000..2c5702d
--- /dev/null
+++ b/src/js/page.js
@@ -0,0 +1,907 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+var page = {
+  startX: 150,
+  startY: 150,
+  endX: 400,
+  endY: 300,
+  moveX: 0,
+  moveY: 0,
+  pageWidth: 0,
+  pageHeight: 0,
+  visibleWidth: 0,
+  visibleHeight: 0,
+  dragging: false,
+  moving: false,
+  resizing: false,
+  isMouseDown: false,
+  scrollXCount: 0,
+  scrollYCount: 0,
+  scrollX: 0,
+  scrollY: 0,
+  captureWidth: 0,
+  captureHeight: 0,
+  isSelectionAreaTurnOn: false,
+  fixedElements_ : [],
+  marginTop: 0,
+  marginLeft: 0,
+  modifiedBottomRightFixedElements: [],
+  originalViewPortWidth: document.documentElement.clientWidth,
+  defaultScrollBarWidth: 17, // Default scroll bar width on windows platform.
+
+  hookBodyScrollValue: function(needHook) {
+    document.documentElement.setAttribute(
+        "__screen_capture_need_hook_scroll_value__", needHook);
+    var event = document.createEvent('Event');
+    event.initEvent('__screen_capture_check_hook_status_event__', true, true);
+    document.documentElement.dispatchEvent(event);
+  },
+
+  /**
+   * Determine if the page scrolled to bottom or right.
+   */
+  isScrollToPageEnd: function(coordinate) {
+    var body = document.body;
+    var docElement = document.documentElement;
+    if (coordinate == 'x')
+      return docElement.clientWidth + body.scrollLeft == body.scrollWidth;
+    else if (coordinate == 'y')
+      return docElement.clientHeight + body.scrollTop == body.scrollHeight;
+  },
+
+  /**
+   * Detect if the view port is located to the corner of page.
+   */
+  detectPagePosition: function() {
+    var body = document.body;
+    var pageScrollTop = body.scrollTop;
+    var pageScrollLeft = body.scrollLeft;
+    if (pageScrollTop == 0 && pageScrollLeft == 0) {
+      return 'top_left';
+    } else if (pageScrollTop == 0 && this.isScrollToPageEnd('x')) {
+      return 'top_right';
+    } else if (this.isScrollToPageEnd('y') && pageScrollLeft == 0) {
+      return 'bottom_left';
+    } else if (this.isScrollToPageEnd('y') && this.isScrollToPageEnd('x')) {
+      return 'bottom_right';
+    }
+    return null;
+  },
+
+  /**
+   * Detect fixed-positioned element's position in the view port.
+   * @param {Element} elem
+   * @return {String|Object} Return position of the element in the view port:
+   *   top_left, top_right, bottom_left, bottom_right, or null.
+   */
+  detectCapturePositionOfFixedElement: function(elem) {
+    var docElement = document.documentElement;
+    var viewPortWidth = docElement.clientWidth;
+    var viewPortHeight = docElement.clientHeight;
+    var offsetWidth = elem.offsetWidth;
+    var offsetHeight = elem.offsetHeight;
+    var offsetTop = elem.offsetTop;
+    var offsetLeft = elem.offsetLeft;
+    var result = [];
+
+    // Compare distance between element and the edge of view port to determine
+    // the capture position of element.
+    if (offsetTop <= viewPortHeight - offsetTop - offsetHeight) {
+      result.push('top');
+    } else if (offsetTop < viewPortHeight) {
+      result.push('bottom');
+    }
+    if (offsetLeft <= viewPortWidth - offsetLeft - offsetWidth) {
+      result.push('left');
+    } else if (offsetLeft < viewPortWidth) {
+      result.push('right');
+    }
+
+    // If the element is out of view port, then ignore.
+    if (result.length != 2)
+      return null;
+    return result.join('_');
+  },
+
+  restoreFixedElements: function() {
+    this.fixedElements_.forEach(function(element) {
+      element[1].style.visibility = 'visible';
+    });
+    this.fixedElements_ = [];
+  },
+
+  /**
+   * Iterate DOM tree and cache visible fixed-position elements.
+   */
+  cacheVisibleFixedPositionedElements: function() {
+    var nodeIterator = document.createNodeIterator(
+        document.documentElement,
+        NodeFilter.SHOW_ELEMENT,
+        null,
+        false
+    );
+    var currentNode;
+    while (currentNode = nodeIterator.nextNode()) {
+      var nodeComputedStyle =
+          document.defaultView.getComputedStyle(currentNode, "");
+      // Skip nodes which don't have computeStyle or are invisible.
+      if (!nodeComputedStyle)
+        continue;
+      if (nodeComputedStyle.position == "fixed" &&
+          nodeComputedStyle.display != 'none' &&
+          nodeComputedStyle.visibility != 'hidden') {
+        var position =
+          this.detectCapturePositionOfFixedElement(currentNode);
+        if (position)
+          this.fixedElements_.push([position, currentNode]);
+      }
+    }
+  },
+
+  // Handle fixed-position elements for capture.
+  handleFixedElements: function(capturePosition) {
+    var docElement = document.documentElement;
+    var body = document.body;
+
+    // If page has no scroll bar, then return directly.
+    if (docElement.clientHeight == body.scrollHeight &&
+        docElement.clientWidth == body.scrollWidth)
+      return;
+    
+    if (!this.fixedElements_.length) {
+      this.cacheVisibleFixedPositionedElements();
+    }
+
+    this.fixedElements_.forEach(function(element) {
+      if (element[0] == capturePosition)
+        element[1].style.visibility = 'visible';
+      else
+        element[1].style.visibility = 'hidden';
+    });
+  },
+
+  handleSecondToLastCapture: function() {
+    var docElement = document.documentElement;
+    var body = document.body;
+    var bottomPositionElements = [];
+    var rightPositionElements = [];
+    var that = this;
+    this.fixedElements_.forEach(function(element) {
+      var position = element[0];
+      if (position == 'bottom_left' || position == 'bottom_right') {
+        bottomPositionElements.push(element[1]);
+      } else if (position == 'bottom_right' || position == 'top_right') {
+        rightPositionElements.push(element[1]);
+      }
+    });
+
+    // Determine if the current capture is last but one.
+    var remainingCaptureHeight = body.scrollHeight - docElement.clientHeight -
+      body.scrollTop;
+    if (remainingCaptureHeight > 0 &&
+        remainingCaptureHeight < docElement.clientHeight) {
+      bottomPositionElements.forEach(function(element) {
+        if (element.offsetHeight > remainingCaptureHeight) {
+          element.style.visibility = 'visible';
+          var originalBottom = window.getComputedStyle(element).bottom;
+          that.modifiedBottomRightFixedElements.push(
+            ['bottom', element, originalBottom]);
+          element.style.bottom = -remainingCaptureHeight + 'px';
+        }
+      });
+    }
+
+    var remainingCaptureWidth = body.scrollWidth - docElement.clientWidth -
+      body.scrollLeft;
+    if (remainingCaptureWidth > 0 &&
+        remainingCaptureWidth < docElement.clientWidth) {
+      rightPositionElements.forEach(function(element) {
+        if (element.offsetWidth > remainingCaptureWidth) {
+          element.style.visibility = 'visible';
+          var originalRight = window.getComputedStyle(element).right;
+          that.modifiedBottomRightFixedElements.push(
+            ['right', element, originalRight]);
+          element.style.right = -remainingCaptureWidth + 'px';
+        }
+      });
+    }
+  },
+
+  restoreBottomRightOfFixedPositionElements: function() {
+    this.modifiedBottomRightFixedElements.forEach(function(data) {
+      var property = data[0];
+      var element = data[1];
+      var originalValue = data[2];
+      element.style[property] = originalValue;
+    });
+    this.modifiedBottomRightFixedElements = [];
+  },
+  
+  hideAllFixedPositionedElements: function() {
+    this.fixedElements_.forEach(function(element) {
+      element[1].style.visibility = 'hidden';
+    });
+  },
+
+  hasScrollBar: function(axis) {
+    var body = document.body;
+    var docElement = document.documentElement;
+    if (axis == 'x') {
+      if (window.getComputedStyle(body).overflowX == 'scroll')
+        return true;
+      return Math.abs(body.scrollWidth - docElement.clientWidth) >=
+          page.defaultScrollBarWidth;
+    } else if (axis == 'y') {
+      if (window.getComputedStyle(body).overflowY == 'scroll')
+        return true;
+      return Math.abs(body.scrollHeight - docElement.clientHeight) >=
+          page.defaultScrollBarWidth;
+    }
+  },
+
+  getOriginalViewPortWidth: function() {
+    chrome.extension.sendMessage({ msg: 'original_view_port_width'},
+      function(originalViewPortWidth) {
+        if (originalViewPortWidth) {
+          page.originalViewPortWidth = page.hasScrollBar('y') ?
+            originalViewPortWidth - page.defaultScrollBarWidth : originalViewPortWidth;
+        } else {
+          page.originalViewPortWidth = document.documentElement.clientWidth;
+        }
+      });
+  },
+  
+  calculateSizeAfterZooming: function(originalSize) {
+    var originalViewPortWidth = page.originalViewPortWidth;
+    var currentViewPortWidth = document.documentElement.clientWidth;
+    if (originalViewPortWidth == currentViewPortWidth)
+      return originalSize;
+    return Math.round(
+        originalViewPortWidth * originalSize / currentViewPortWidth);
+  },
+
+  getZoomLevel: function() {
+    return page.originalViewPortWidth / document.documentElement.clientWidth;
+  },
+
+  handleRightFloatBoxInGmail: function() {
+    var mainframe = document.getElementById('canvas_frame');
+    var boxContainer = document.querySelector('body > .dw');
+    var fBody = mainframe.contentDocument.body;
+    if (fBody.clientHeight + fBody.scrollTop == fBody.scrollHeight) {
+      boxContainer.style.display = 'block';
+    } else {
+      boxContainer.style.display = 'none';
+    }
+  },
+
+  getViewPortSize: function() {
+    var result = {
+      width: document.documentElement.clientWidth,
+      height: document.documentElement.clientHeight
+    };
+
+    if (document.compatMode == 'BackCompat') {
+      result.width = document.body.clientWidth;
+      result.height = document.body.clientHeight;
+    }
+
+    return result;
+  },
+
+  /**
+   * Check if the page is only made of invisible embed elements.
+   */
+  checkPageIsOnlyEmbedElement: function() {
+    var bodyNode = document.body.children;
+    var isOnlyEmbed = false;
+    for (var i = 0; i < bodyNode.length; i++) {
+      var tagName = bodyNode[i].tagName;
+      if (tagName == 'OBJECT' || tagName == 'EMBED' || tagName == 'VIDEO' ||
+          tagName == 'SCRIPT' || tagName == 'LINK') {
+        isOnlyEmbed = true;
+      } else if (bodyNode[i].style.display != 'none'){
+        isOnlyEmbed = false;
+        break;
+      }
+    }
+    return isOnlyEmbed;
+  },
+
+  isGMailPage: function(){
+    var hostName = window.location.hostname;
+    if (hostName == 'mail.google.com' &&
+        document.getElementById('canvas_frame')) {
+      return true;
+    }
+    return false;
+  },
+
+  /**
+  * Receive messages from background page, and then decide what to do next
+  */
+  addMessageListener: function() {
+    chrome.extension.onMessage.addListener(function(request, sender, response) {
+      if (page.isSelectionAreaTurnOn) {
+        page.removeSelectionArea();
+      }
+      switch (request.msg) {
+        case 'capture_window': response(page.getWindowSize()); break;
+        case 'show_selection_area': page.showSelectionArea(); break;
+        case 'scroll_init': // Capture whole page.
+          response(page.scrollInit(0, 0, document.body.scrollWidth,
+              document.body.scrollHeight, 'captureWhole'));
+          break;
+        case 'scroll_next':
+          page.visibleWidth = request.visibleWidth;
+          page.visibleHeight = request.visibleHeight;
+          response(page.scrollNext());
+          break;
+        case 'capture_selected':
+          response(page.scrollInit(
+              page.startX, page.startY,
+              page.calculateSizeAfterZooming(page.endX - page.startX),
+              page.calculateSizeAfterZooming(page.endY - page.startY),
+              'captureSelected'));
+          break;
+      }
+    });
+  },
+
+  /**
+  * Send Message to background page
+  */
+  sendMessage: function(message) {
+    chrome.extension.sendMessage(message);
+  },
+
+  /**
+  * Initialize scrollbar position, and get the data browser
+  */
+  scrollInit: function(startX, startY, canvasWidth, canvasHeight, type) {
+    this.hookBodyScrollValue(true);
+    page.captureHeight = canvasHeight;
+    page.captureWidth = canvasWidth;
+    var docWidth = document.body.scrollWidth;
+    var docHeight = document.body.scrollHeight;
+    window.scrollTo(startX, startY);
+
+    this.handleFixedElements('top_left');
+    this.handleSecondToLastCapture();
+
+    if (page.isGMailPage() && type == 'captureWhole') {
+      var frame = document.getElementById('canvas_frame');
+      docHeight = page.captureHeight = canvasHeight =
+          frame.contentDocument.height;
+      docWidth = page.captureWidth = canvasWidth = frame.contentDocument.width;
+      frame.contentDocument.body.scrollTop = 0;
+      frame.contentDocument.body.scrollLeft = 0;
+      page.handleRightFloatBoxInGmail();
+    }
+    page.scrollXCount = 0;
+    page.scrollYCount = 1;
+    page.scrollX = window.scrollX; // document.body.scrollLeft
+    page.scrollY = window.scrollY;
+    var viewPortSize = page.getViewPortSize();
+    return {
+      'msg': 'scroll_init_done',
+      'startX': page.calculateSizeAfterZooming(startX),
+      'startY': page.calculateSizeAfterZooming(startY),
+      'scrollX': window.scrollX,
+      'scrollY': window.scrollY,
+      'docHeight': docHeight,
+      'docWidth': docWidth,
+      'visibleWidth': viewPortSize.width,
+      'visibleHeight': viewPortSize.height,
+      'canvasWidth': canvasWidth,
+      'canvasHeight': canvasHeight,
+      'scrollXCount': 0,
+      'scrollYCount': 0,
+      'zoom': page.getZoomLevel()
+    };
+  },
+
+  /**
+  * Calculate the next position of the scrollbar
+  */
+  scrollNext: function() {
+    if (page.scrollYCount * page.visibleWidth >= page.captureWidth) {
+      page.scrollXCount++;
+      page.scrollYCount = 0;
+    }
+    if (page.scrollXCount * page.visibleHeight < page.captureHeight) {
+      this.restoreBottomRightOfFixedPositionElements();
+      var viewPortSize = page.getViewPortSize();
+      window.scrollTo(
+          page.scrollYCount * viewPortSize.width + page.scrollX,
+          page.scrollXCount * viewPortSize.height + page.scrollY);
+
+      var pagePosition = this.detectPagePosition();
+      if (pagePosition) {
+        this.handleFixedElements(pagePosition);
+      } else {
+        this.hideAllFixedPositionedElements();
+      }
+      this.handleSecondToLastCapture();
+
+      if (page.isGMailPage()) {
+        var frame = document.getElementById('canvas_frame');
+        frame.contentDocument.body.scrollLeft =
+            page.scrollYCount * viewPortSize.width;
+        frame.contentDocument.body.scrollTop =
+            page.scrollXCount * viewPortSize.height;
+        page.handleRightFloatBoxInGmail();
+      }
+      var x = page.scrollXCount;
+      var y = page.scrollYCount;
+      page.scrollYCount++;
+      return { msg: 'scroll_next_done',scrollXCount: x, scrollYCount: y };
+    }  else {
+      window.scrollTo(page.startX, page.startY);
+      this.restoreFixedElements();
+      this.hookBodyScrollValue(false);
+      return {'msg': 'scroll_finished'};
+    }
+  },
+
+  /**
+  * Show the selection Area
+  */
+  showSelectionArea: function() {
+    page.createFloatLayer();
+    setTimeout(page.createSelectionArea, 100);
+  },
+
+  getWindowSize: function() {
+    var docWidth = document.body.clientWidth;
+    var docHeight = document.body.clientHeight;
+    if (page.isGMailPage()) {
+      var frame = document.getElementById('canvas_frame');
+      docHeight = frame.contentDocument.height;
+      docWidth = frame.contentDocument.width;
+    }
+    return {'msg':'capture_window',
+            'docWidth': docWidth,
+            'docHeight': docHeight};
+  },
+
+  getSelectionSize: function() {
+    page.removeSelectionArea();
+    setTimeout(function() {
+      page.sendMessage({
+        'msg': 'capture_selected',
+        'x': page.startX,
+        'y': page.startY,
+        'width': page.endX - page.startX,
+        'height': page.endY - page.startY,
+        'visibleWidth': document.documentElement.clientWidth,
+        'visibleHeight': document.documentElement.clientHeight,
+        'docWidth': document.body.clientWidth,
+        'docHeight': document.body.clientHeight
+      })}, 100);
+  },
+
+  /**
+  * Create a float layer on the webpage
+  */
+  createFloatLayer: function() {
+    page.createDiv(document.body, 'sc_drag_area_protector');
+  },
+  
+  matchMarginValue: function(str) {
+    return str.match(/\d+/);
+  },
+
+  /**
+  * Load the screenshot area interface
+  */
+  createSelectionArea: function() {
+    var areaProtector = $('sc_drag_area_protector');
+    var zoom = page.getZoomLevel();
+    var bodyStyle = window.getComputedStyle(document.body, null);
+    if ('relative' == bodyStyle['position']) {
+      page.marginTop = page.matchMarginValue(bodyStyle['marginTop']);
+      page.marginLeft = page.matchMarginValue(bodyStyle['marginLeft']);
+      areaProtector.style.top =  - parseInt(page.marginTop) + 'px';
+      areaProtector.style.left =  - parseInt(page.marginLeft) + 'px';
+    }
+    areaProtector.style.width =
+      Math.round((document.body.clientWidth + parseInt(page.marginLeft)) / zoom) + 'px';
+    areaProtector.style.height =
+      Math.round((document.body.clientHeight + parseInt(page.marginTop)) / zoom) + 'px';
+    areaProtector.onclick = function() {
+      event.stopPropagation();
+      return false;
+    };
+
+    // Create elements for area capture.
+    page.createDiv(areaProtector, 'sc_drag_shadow_top');
+    page.createDiv(areaProtector, 'sc_drag_shadow_bottom');
+    page.createDiv(areaProtector, 'sc_drag_shadow_left');
+    page.createDiv(areaProtector, 'sc_drag_shadow_right');
+
+    var areaElement = page.createDiv(areaProtector, 'sc_drag_area');
+    page.createDiv(areaElement, 'sc_drag_container');
+    page.createDiv(areaElement, 'sc_drag_size');
+
+    // Add event listener for 'cancel' and 'capture' button.
+    var cancel = page.createDiv(areaElement, 'sc_drag_cancel');
+    cancel.addEventListener('mousedown', function () {
+      // Remove area capture containers and event listeners.
+      page.removeSelectionArea();
+    }, true);
+    cancel.innerHTML = chrome.i18n.getMessage("cancel");
+
+    var crop = page.createDiv(areaElement, 'sc_drag_crop');
+    crop.addEventListener('mousedown', function() {
+      page.removeSelectionArea();
+      page.sendMessage({msg: 'capture_selected'});
+    }, false);
+    crop.innerHTML = chrome.i18n.getMessage('ok');
+
+    page.createDiv(areaElement, 'sc_drag_north_west');
+    page.createDiv(areaElement, 'sc_drag_north_east');
+    page.createDiv(areaElement, 'sc_drag_south_east');
+    page.createDiv(areaElement, 'sc_drag_south_west');
+
+    areaProtector.addEventListener('mousedown', page.onMouseDown, false);
+    document.addEventListener('mousemove', page.onMouseMove, false);
+    document.addEventListener('mouseup', page.onMouseUp, false);
+    $('sc_drag_container').addEventListener('dblclick', function() {
+      page.removeSelectionArea();
+      page.sendMessage({msg: 'capture_selected'});
+    }, false);
+
+    page.pageHeight = $('sc_drag_area_protector').clientHeight;
+    page.pageWidth = $('sc_drag_area_protector').clientWidth;
+
+    var areaElement = $('sc_drag_area');
+    areaElement.style.left = page.getElementLeft(areaElement) + 'px';
+    areaElement.style.top = page.getElementTop(areaElement) + 'px';
+    
+    page.startX = page.getElementLeft(areaElement);
+    page.startY = page.getElementTop(areaElement); 
+    page.endX = page.getElementLeft(areaElement) + 250;
+    page.endY = page.getElementTop(areaElement) + 150;
+    
+    areaElement.style.width = '250px';
+    areaElement.style.height = '150px';
+    page.isSelectionAreaTurnOn = true;
+    page.updateShadow(areaElement);
+    page.updateSize();
+  },
+  
+  getElementLeft: function(obj) {
+    return (document.body.scrollLeft +
+        (document.documentElement.clientWidth - 
+        obj.offsetWidth) / 2);
+  },
+  
+  getElementTop: function(obj) {
+    return (document.body.scrollTop + 
+        (document.documentElement.clientHeight - 200 - 
+        obj.offsetHeight) / 2);
+  },
+
+  /**
+  * Init selection area due to the position of the mouse when mouse down
+  */
+  onMouseDown: function() {
+    if (event.button != 2) {
+      var element = event.target;
+
+      if (element) {
+        var elementName = element.tagName;
+        if (elementName && document) {
+          page.isMouseDown = true;
+
+          var areaElement = $('sc_drag_area');
+          var xPosition = event.pageX;
+          var yPosition = event.pageY;
+
+          if (areaElement) {
+            if (element == $('sc_drag_container')) {
+              page.moving = true;
+              page.moveX = xPosition - areaElement.offsetLeft;
+              page.moveY = yPosition - areaElement.offsetTop;
+            } else if (element == $('sc_drag_north_east')) {
+              page.resizing = true;
+              page.startX = areaElement.offsetLeft;
+              page.startY = areaElement.offsetTop + areaElement.clientHeight;
+            } else if (element == $('sc_drag_north_west')) {
+              page.resizing = true;
+              page.startX = areaElement.offsetLeft + areaElement.clientWidth;
+              page.startY = areaElement.offsetTop + areaElement.clientHeight;
+            } else if (element == $('sc_drag_south_east')) {
+              page.resizing = true;
+              page.startX = areaElement.offsetLeft;
+              page.startY = areaElement.offsetTop;
+            } else if (element == $('sc_drag_south_west')) {
+              page.resizing = true;
+              page.startX = areaElement.offsetLeft + areaElement.clientWidth;
+              page.startY = areaElement.offsetTop;
+            } else {
+              page.dragging = true;
+              page.endX = 0;
+              page.endY = 0;
+              page.endX = page.startX = xPosition;
+              page.endY = page.startY = yPosition;
+            }
+          }
+          event.preventDefault();
+        }
+      }
+    }
+  },
+
+  /**
+  * Change selection area position when mouse moved
+  */
+  onMouseMove: function() {
+    var element = event.target;
+    if (element && page.isMouseDown) {
+      var areaElement = $('sc_drag_area');
+      if (areaElement) {
+        var xPosition = event.pageX;
+        var yPosition = event.pageY;
+        if (page.dragging || page.resizing) {
+          var width = 0;
+          var height = 0;
+          var zoom = page.getZoomLevel();
+          var viewWidth = Math.round(document.body.clientWidth / zoom);
+          var viewHeight = Math.round(document.body.clientHeight / zoom);
+          if (xPosition > viewWidth) {
+            xPosition = viewWidth;
+          } else if (xPosition < 0) {
+            xPosition = 0;
+          }
+          if (yPosition > viewHeight) {
+            yPosition = viewHeight;
+          } else if (yPosition < 0) {
+            yPosition = 0;
+          }
+          page.endX = xPosition;
+          page.endY = yPosition;
+          if (page.startX > page.endX) {
+            width = page.startX - page.endX;
+            areaElement.style.left = xPosition + 'px';
+          } else {
+            width = page.endX - page.startX;
+            areaElement.style.left = page.startX + 'px';
+          }
+          if (page.startY > page.endY) {
+            height = page.startY - page.endY;
+            areaElement.style.top = page.endY + 'px';
+          } else {
+            height = page.endY - page.startY;
+            areaElement.style.top = page.startY + 'px';
+          }
+          areaElement.style.height = height + 'px';
+          areaElement.style.width  = width + 'px';
+          if (window.innerWidth < xPosition) {
+            document.body.scrollLeft = xPosition - window.innerWidth;
+          }
+          if (document.body.scrollTop + window.innerHeight < yPosition + 25) {
+            document.body.scrollTop = yPosition - window.innerHeight + 25;
+          }
+          if (yPosition < document.body.scrollTop) {
+            document.body.scrollTop -= 25;
+          }
+        } else if (page.moving) {
+          var newXPosition = xPosition - page.moveX;
+          var newYPosition = yPosition - page.moveY;
+          if (newXPosition < 0) {
+            newXPosition = 0;
+          } else if (newXPosition + areaElement.clientWidth > page.pageWidth) {
+            newXPosition = page.pageWidth - areaElement.clientWidth;
+          }
+          if (newYPosition < 0) {
+            newYPosition = 0;
+          } else if (newYPosition + areaElement.clientHeight >
+                     page.pageHeight) {
+            newYPosition = page.pageHeight - areaElement.clientHeight;
+          }
+
+          areaElement.style.left = newXPosition + 'px';
+          areaElement.style.top = newYPosition + 'px';
+          page.endX = newXPosition + areaElement.clientWidth;
+          page.startX = newXPosition;
+          page.endY = newYPosition + areaElement.clientHeight;
+          page.startY = newYPosition;
+
+        }
+        var crop = document.getElementById('sc_drag_crop');
+        var cancel = document.getElementById('sc_drag_cancel');
+        if (event.pageY + 25 > document.body.clientHeight) {
+          crop.style.bottom = 0;
+          cancel.style.bottom = 0
+        } else {
+          crop.style.bottom = '-25px';
+          cancel.style.bottom = '-25px';
+        }
+
+        var dragSizeContainer = document.getElementById('sc_drag_size');
+        if (event.pageY < 18) {
+          dragSizeContainer.style.top = 0;
+        } else {
+          dragSizeContainer.style.top = '-18px';
+        }
+        page.updateShadow(areaElement);
+        page.updateSize();
+
+      }
+    }
+  },
+
+ /**
+  * Fix the selection area position when mouse up
+  */
+  onMouseUp: function() {
+    page.isMouseDown = false;
+    if (event.button != 2) {
+      page.resizing = false;
+      page.dragging = false;
+      page.moving = false;
+      page.moveX = 0;
+      page.moveY = 0;
+      var temp;
+      if (page.endX < page.startX) {
+        temp = page.endX;
+        page.endX = page.startX;
+        page.startX = temp;
+      }
+      if (page.endY < page.startY) {
+        temp = page.endY;
+        page.endY = page.startY;
+        page.startY = temp;
+      }
+    }
+  },
+
+  /**
+  * Update the location of the shadow layer
+  */
+  updateShadow: function(areaElement) {
+    $('sc_drag_shadow_top').style.height =
+        parseInt(areaElement.style.top) + 'px';
+    $('sc_drag_shadow_top').style.width = (parseInt(areaElement.style.left) +
+        parseInt(areaElement.style.width) + 1) + 'px';
+    $('sc_drag_shadow_left').style.height =
+        (page.pageHeight - parseInt(areaElement.style.top)) + 'px';
+    $('sc_drag_shadow_left').style.width =
+        parseInt(areaElement.style.left) + 'px';
+
+    var height = (parseInt(areaElement.style.top) +
+        parseInt(areaElement.style.height) + 1);
+    height = (height < 0) ? 0 : height;
+    var width = (page.pageWidth) - 1 - (parseInt(areaElement.style.left) +
+        parseInt(areaElement.style.width));
+    width = (width < 0) ? 0 : width;
+    $('sc_drag_shadow_right').style.height = height + 'px';
+    $('sc_drag_shadow_right').style.width =  width + 'px';
+
+    height = (page.pageHeight - 1 - (parseInt(areaElement.style.top) +
+        parseInt(areaElement.style.height)));
+    height = (height < 0) ? 0 : height;
+    width = (page.pageWidth) - parseInt(areaElement.style.left);
+    width = (width < 0) ? 0 : width;
+    $('sc_drag_shadow_bottom').style.height = height + 'px';
+    $('sc_drag_shadow_bottom').style.width = width + 'px';
+  },
+
+  /**
+  * Remove selection area
+  */
+  removeSelectionArea: function() {
+    document.removeEventListener('mousedown', page.onMouseDown, false);
+    document.removeEventListener('mousemove', page.onMouseMove, false);
+    document.removeEventListener('mouseup', page.onMouseUp, false);
+    $('sc_drag_container').removeEventListener('dblclick',function() {
+      page.removeSelectionArea();
+      page.sendMessage({msg: 'capture_selected'});}, false);
+    page.removeElement('sc_drag_area_protector');
+    page.removeElement('sc_drag_area');
+    page.isSelectionAreaTurnOn = false;
+  },
+
+  /**
+  * Refresh the size info
+  */
+  updateSize: function() {
+    var width = Math.abs(page.endX - page.startX);
+    var height = Math.abs(page.endY - page.startY);
+    $('sc_drag_size').innerText = page.calculateSizeAfterZooming(width) +
+      ' x ' + page.calculateSizeAfterZooming(height);
+  },
+
+  /**
+  * create div
+  */
+  createDiv: function(parent, id) {
+    var divElement = document.createElement('div');
+    divElement.id = id;
+    parent.appendChild(divElement);
+    return divElement;
+  },
+
+  /**
+  * Remove an element
+  */
+  removeElement: function(id) {
+    if($(id)) {
+      $(id).parentNode.removeChild($(id));
+    }
+  },
+
+  injectCssResource: function(cssResource) {
+    var css = document.createElement('LINK');
+    css.type = 'text/css';
+    css.rel = 'stylesheet';
+    css.href = chrome.extension.getURL(cssResource);
+    (document.head || document.body || document.documentElement).
+        appendChild(css);
+  },
+
+  injectJavaScriptResource: function(scriptResource) {
+    var script = document.createElement("script");
+    script.type = "text/javascript";
+    script.charset = "utf-8";
+    script.src = chrome.extension.getURL(scriptResource);
+    (document.head || document.body || document.documentElement).
+        appendChild(script);
+  },
+
+  /**
+  * Remove an element
+  */
+  init: function() { 
+    if (document.body.hasAttribute('screen_capture_injected')) {
+      return;
+    }
+    if (isPageCapturable()) {
+      chrome.extension.sendMessage({msg: 'page_capturable'});
+    } else {
+      chrome.extension.sendMessage({msg: 'page_uncapturable'});
+    }
+    this.injectCssResource('style.css');
+    this.addMessageListener();
+    this.injectJavaScriptResource("js/page_context.js");
+
+    // Retrieve original width of view port and cache.
+    page.getOriginalViewPortWidth();
+  }
+};
+
+/**
+ * Indicate if the current page can be captured.
+ */
+var isPageCapturable = function() {
+  return !page.checkPageIsOnlyEmbedElement();
+};
+
+function $(id) {
+  return document.getElementById(id);
+}
+
+page.init();
+
+window.addEventListener('resize', function() {
+  if (page.isSelectionAreaTurnOn) {
+    page.removeSelectionArea();
+    page.showSelectionArea();
+  }
+
+  // Reget original width of view port if browser window resized or page zoomed.
+  page.getOriginalViewPortWidth();
+}, false);
+
+// Send page url for retriving and parsing access token for facebook and picasa.
+var message = {
+  msg: 'url_for_access_token',
+  url: window.location.href
+}
+if (window.location.href.indexOf('https://api.weibo.com/oauth2/default.html') == 0) {
+  message.siteId = 'sina'
+}
+page.sendMessage(message);
