chrome.js
Summary
Widget Chrome Library
Library to make resizable widget chrome.
Version: 0.2
The user does not need to do anything for the chrome to be visible.
Only include the script and the skin file and it should work.
, 0.1
Initial implementation
Author: Vivek Jishtu
| Class Summary | |
| WidgetChrome | A class which paints the chrome and handles resizing. |
/* * Copyright (c) 2008, Opera Software ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Opera Software ASA nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY OPERA SOFTWARE ASA ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL OPERA SOFTWARE ASA BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @fileoverview * Widget Chrome Library * * Library to make resizable widget chrome. * * @version 0.2 * The user does not need to do anything for the chrome to be visible. * Only include the script and the skin file and it should work. * * @version 0.1 * Initial implementation * * @author Vivek Jishtu */ /** * This class is used to make the widget chrome. In your project you need to * use the object WidgetChrome. * * @class * A class which paints the chrome and handles resizing. */ var WidgetChrome = new function() { /** * Array of chrome pieces ID's. These ID's are used in CSS * while designing the skin. * * @type Array */ var _chromePiecesId = ["chrome_middle_content", "chrome_top_left", "chrome_top_middle", "chrome_top_right", "chrome_middle_left", "chrome_middle_right", "chrome_bottom_left", "chrome_bottom_middle", "chrome_bottom_right"]; /** * Array of HTMLElements which makeup the widget chrome. * * @type Array */ var _chromePieces = {}; /** * The rootElement on which the chrome is painted. * * @type HTMLElement */ var _rootElement = null; /** * The root node which holds the widget chrome. * It is the child of rootElement. * * @type HTMLDivElement */ var _chromeRoot; var _sizeControl; var _self = this; /** * The minimum width for the widget * * @public * @type Integer */ this.minWidth = 50; /** * The minimum height for the widget * * @public * @type Integer */ this.minHeight = 100; /** * Reference to the config button * * @public * @type HTMLButtonElement */ this.ButtonConfig = createButton("btnConfig"); /** * Reference to the close button * * @public * @type HTMLButtonElement */ this.ButtonClose = createButton("btnClose"); /** * Overload this function incase you want * to handle the close button click event. * * @param {Event} event */ this.ButtonClose.onclick = function(event) { window.close(); } /** * This is just a stub you have to overload * this function incase you want the config * button to work. * * @param {Event} event */ this.ButtonConfig.onclick = function(event) { opera.postError("Config clicked"); } /** * A light wrapper around the document.getElementById * * @param {String} id * @returns {HTMLElement} The HTMLElement with that id. */ function $(id) { return document.getElementById(id); } /** * Set if the scrollbars should be visible if content is more * than visible area. * * @param {Boolean} state Can be true to enable scrollbars and false to disable them. */ this.showScrollBars = function(state) { var contentArea = $("chrome_middle_content"); if (state == true) contentArea.style.overflow = "auto"; else contentArea.style.overflow = "hidden"; } /** * To set the skin used as the Chrome. * * @param {String} skinName Name of the skin you want to add. */ this.setSkin = function(skinName) { var head = document.getElementsByTagName('head').item(0); var link = document.createElement("link"); link.rel = "stylesheet"; link.type = "text/css"; link.id = skinName; link.title = skinName; link.media = "screen"; link.href = skinName + "/skin.css"; head.appendChild(link); } /** * Inits the basic Widget Chrome. Creates and adds the * <strong>HTMLElements</strong> to the rootElement. * * @private */ function init() { _rootElement = document.body; // Root node which holds the other divs _chromeRoot = createDiv("__widget_chrome_root__"); _chromeRoot.setAttribute("data-not-chrome-content", "true"); addChromePiecesToRoot(); _rootElement.insertBefore(_chromeRoot, _rootElement.firstChild); // Create divs to resize the widget sizerControls(); addWidgetControls(); $("lblTitle").innerHTML = document.title; addBodyToContentArea(); _self.redraw(); } /** * Function used to move all the elements from the body * to chrome_middle_content unless it has been tagged * as a rootElement. * * @private */ function addBodyToContentArea() { var contentArea = $("chrome_middle_content"); var currentNode = document.body.firstChild; var nextNode; while (currentNode) { nextNode = currentNode.nextSibling; if (currentNode.getAttribute && currentNode.getAttribute("data-not-chrome-content")) { // If its part of the rootElement do not move it } else { contentArea.appendChild(currentNode); } currentNode = nextNode; } } /** * Adds the widget control elements to the chrome. * Titlebar caption, Config button and Close button. * * @private */ function addWidgetControls() { _chromeRoot.appendChild(createDiv("lblTitle")); _chromeRoot.appendChild(_self.ButtonConfig); _chromeRoot.appendChild(_self.ButtonClose); } /** * This function handles the creation and also control * or the sizer control which allows the widget to be * resized. * * @private */ function sizerControls() { _sizeControl = createDiv("sizerControl"); _sizeControl.setAttribute("data-not-chrome-content", "true"); with(_sizeControl.style) { position = "absolute"; top = "0px"; left = "0px"; border = "1px dotted black"; display = "none"; } document.body.appendChild(_sizeControl); var windowX = document.body.clientWidth; var windowY = document.body.clientHeight; function resizer_MouseDown(event) { var x = event.clientX; var y = event.clientY; var oldWindowX = document.body.clientWidth; var oldWindowY = document.body.clientHeight; $("sizerControl").style.display = "block"; $("sizerControl").style.height = window.innerHeight - 5 + "px"; $("sizerControl").style.width = window.innerWidth - 5 + "px"; window.resizeTo(window.innerWidth + 5, window.innerHeight + 5); function window_MouseMove(event) { window.scrollTo(0, 0); windowX = oldWindowX + event.clientX - x; windowY = oldWindowY + event.clientY - y; if (windowX > window.innerWidth) window.resizeTo(windowX + 5, window.innerHeight); if (windowY > window.innerHeight) window.resizeTo(window.innerWidth, windowY + 5); if (_self.minWidth > windowX) return; if (_self.minHeight > windowY) return; document.body.style.height = document.body.clientHeight - 2 + "px"; document.body.style.width = document.body.clientWidth - 2 + "px"; $("sizerControl").style.height = windowY - 3 + "px"; $("sizerControl").style.width = windowX - 3 + "px"; } function window_MouseUp(event) { if (_self.minWidth > windowX) windowX = _self.minWidth; if (_self.minHeight > windowY) windowY = _self.minHeight; window.resizeTo(windowX, windowY); document.body.style.height = window.innerHeight + "px"; document.body.style.width = window.innerWidth + "px"; $("sizerControl").style.display = "none"; _self.redraw(); window.removeEventListener("mousemove", window_MouseMove, true); window.removeEventListener("mouseup", window_MouseUp, true); } window.addEventListener("mousemove", window_MouseMove, true); window.addEventListener("mouseup", window_MouseUp, true); } //The function used to resize the window in the SW Direction. $("chrome_bottom_right").onmousedown = resizer_MouseDown; } /** * Create the chrome pieces and append them * to the rootElement. * * @private */ function addChromePiecesToRoot() { for (var x in _chromePiecesId) { var id = _chromePiecesId[x]; _chromePieces[id] = createDiv(id); _chromeRoot.appendChild(_chromePieces[id]); } } /** * Helper function to create a div * * @param {String} id * @private */ function createDiv(id) { var div = document.createElement("div"); div.id = id; return div; } /** * Helper function to create a button * * @param {String} id * @private */ function createButton(id) { var button = document.createElement("button"); button.setAttribute("type", "button"); button.id = id; return button; } /** * A public function to redraw the chrome. * * @public */ this.redraw = function() { window.scrollTo(0, 0); document.body.style.top = "0px"; document.body.style.left = "0px"; document.body.style.width = window.innerWidth + "px"; document.body.style.height = window.innerHeight + "px"; _chromeRoot.style.width = document.body.clientWidth + "px"; _chromeRoot.style.height = document.body.clientHeight + "px"; var _width = _chromeRoot.clientWidth; var _height = _chromeRoot.clientHeight; _chromePieces['chrome_top_middle'].style.width = _width - (_chromePieces['chrome_top_left'].clientWidth + _chromePieces['chrome_top_right'].clientWidth) + "px"; _chromePieces['chrome_top_middle'].style.left = _chromePieces['chrome_top_left'].clientWidth + "px"; _chromePieces['chrome_bottom_middle'].style.width = _width - (_chromePieces['chrome_bottom_left'].clientWidth + _chromePieces['chrome_bottom_right'].clientWidth) + "px"; _chromePieces['chrome_bottom_middle'].style.left = _chromePieces['chrome_bottom_left'].clientWidth + "px"; _chromePieces['chrome_middle_left'].style.height = _height - (_chromePieces['chrome_top_left'].clientHeight + _chromePieces['chrome_bottom_left'].clientHeight) + "px"; _chromePieces['chrome_middle_right'].style.height = _height - (_chromePieces['chrome_top_right'].clientHeight + _chromePieces['chrome_bottom_right'].clientHeight) + "px"; _content = _chromePieces['chrome_middle_content']; _content.style.top = _chromePieces['chrome_top_middle'].clientHeight + "px"; _content.style.left = _chromePieces['chrome_middle_left'].clientWidth + "px"; _content.style.height = _height - (_chromePieces['chrome_top_middle'].clientHeight + _chromePieces['chrome_bottom_middle'].clientHeight) + "px"; _content.style.width = _width - (_chromePieces['chrome_middle_left'].clientWidth + _chromePieces['chrome_middle_right'].clientWidth) + "px"; } /** * This functions allows you to automatically size a HTMLElement * to the widget content area. * * @param {Object} element Can be a HTMLElement or id of an element * @public */ this.autoResize = function(element) { if (typeof element == "string") element = document.getElementById(element); if (!element) throw "Cannot find the element to autoResize"; with(element.style) { position = "absolute"; top = "0px"; left = "0px"; height = "100%"; width = "100%"; overflow = "auto"; } } /** * This functions allows you to add HTMLElements * to the widget chrome. Incase you want to add any extra * button you can use this function to do that. * * @param {Object} element Can be a HTMLElement or id of an element * @public */ this.addElementToChrome = function(element) { if (typeof element == "string") element = document.getElementById(element); if (!element) throw "Cannot add the element to the Widget Chrome"; _chromeRoot.appendChild(element); } /** * This function makes the widget fullscreen. This function * is normally used on a small screen device to open a widget * fullscreen. * * @public */ this.setFullScreen = function() { window.moveTo(0, 0); window.resizeTo(screen.availWidth, screen.availHeight); _self.redraw(); } /** * Function to enable a stylesheet at runtime. * You can switch the skins used on your widget. * * @param {String} title The title attribute of the stylesheet you want to enable * @public */ this.enableStyleSheet = function(title) { var stylesheets = document.getElementsByTagName("link"); var x, stylesheet; for (x = 0; x < stylesheets.length; x++) { stylesheet = stylesheets[x]; if (stylesheet.getAttribute("rel").indexOf("stylesheet") != -1) { if (stylesheet.getAttribute("title") == title) stylesheet.disabled = false; } } _self.redraw(); } /** * Function to disable a stylesheet at runtime. * You can switch the skins used on your widget. * * @param {String} title The title attribute of the stylesheet you want to disable * @public */ this.disableStyleSheet = function(title) { var stylesheets = document.getElementsByTagName("link"); var x, stylesheet; for (x = 0; x < stylesheets.length; x++) { stylesheet = stylesheets[x]; if (stylesheet.getAttribute("rel").indexOf("stylesheet") != -1) { if (stylesheet.getAttribute("title") == title) stylesheet.disabled = true; } } _self.redraw(); } /** * Changes the title of the widget. * * @param {String} title The title that is displayed in the caption bar. * @public */ this.setTitle = function(title) { //Cleaup any HTML from the tile. document.title = title.replace(/<\/?[a-z][a-z0-9]*[^<>]*>/g, ""); $("lblTitle").innerHTML = title; } /* * Call the private init function. * If the document has loaded call the init, if its not * call it when the DOMContentLoaded event is called. */ if (document.body) init(); else window.addEventListener("DOMContentLoaded", init, false); } ();;
Documentation generated by JSDoc on Tue Jul 22 10:32:34 2008