blob: 5d7575a5078b5faafde6501e2e784c54ca0f8428 [file] [log] [blame]
/*
* weinre is available under *either* the terms of the modified BSD license *or* the
* MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
*
* Copyright (c) 2010, 2011 IBM Corporation
*/
requireClass ../common/IDGenerator
requireClass ../common/Weinre
//-----------------------------------------------------------------------------
class CSSStore
this.styleSheetMap = {}
this.styleRuleMap = {}
this.styleDeclMap = {}
this.testElement = document.createElement("div")
//-----------------------------------------------------------------------------
init
var Properties = []
//-----------------------------------------------------------------------------
static method addCSSProperties(properties)
Properties = properties
//-----------------------------------------------------------------------------
method getInlineStyle(node)
var styleObject = this._buildMirrorForStyle(node.style, true)
for (var i=0; i<styleObject.cssProperties.length; i++) {
styleObject.cssProperties[i].status = "style"
}
return styleObject
//-----------------------------------------------------------------------------
method getComputedStyle(node)
if (!node) return {}
if (node.nodeType != Node.ELEMENT_NODE) return {}
var styleObject = this._buildMirrorForStyle(window.getComputedStyle(node), false)
return styleObject
//-----------------------------------------------------------------------------
method getMatchedCSSRules(node)
var result = []
for (var i=0; i<document.styleSheets.length; i++) {
var styleSheet = document.styleSheets[i]
if (!styleSheet.cssRules) continue
for (var j=0; j<styleSheet.cssRules.length; j++) {
var cssRule = styleSheet.cssRules[j]
if (!_elementMatchesSelector(node, cssRule.selectorText)) continue
var object = {}
object.ruleId = this._getStyleRuleId(cssRule)
object.selectorText = cssRule.selectorText
object.style = this._buildMirrorForStyle(cssRule.style, true)
result.push(object)
}
}
return result
//-----------------------------------------------------------------------------
method getStyleAttributes(node)
var result = {}
return result
//-----------------------------------------------------------------------------
method getPseudoElements(node)
var result = []
return result
//-----------------------------------------------------------------------------
method setPropertyText(styleId, propertyIndex, text, overwrite)
var styleDecl = Weinre.cssStore._getStyleDecl(styleId)
if (!styleDecl) {
Weinre.logWarning("requested style not available: " + styleId)
return null
}
var mirror = styleDecl.__weinre__mirror
if (!mirror) {
Weinre.logWarning("requested mirror not available: " + styleId)
return null
}
var properties = mirror.cssProperties
// parse the css text
var propertyMirror = this._parseProperty(text)
// remove property
if (null == propertyMirror) {
this._removePropertyFromMirror(mirror, propertyIndex)
properties = mirror.cssProperties
}
// add or replace property
else {
// if replacing, remove the old one
this._removePropertyFromMirror(mirror, propertyIndex)
properties = mirror.cssProperties
// index properties by name
var propertyIndices = {}
for (var i=0; i<properties.length; i++) {
propertyIndices[properties[i].name] = i
}
// add the new ones, or replacing ones
for (var i=0; i<propertyMirror.cssProperties.length; i++) {
if (propertyIndices[propertyMirror.cssProperties[i].name] != null) {
// property already exists, just replace it
properties[propertyIndices[propertyMirror.cssProperties[i].name]] = propertyMirror.cssProperties[i]
}
else {
// new property, add it
properties.push(propertyMirror.cssProperties[i])
}
}
for (var key in propertyMirror.shorthandValues) {
mirror.shorthandValues[key] = propertyMirror.shorthandValues[key]
}
}
properties.sort(function(p1,p2) {
if (p1.name < p2.name) return -1
else if (p1.name > p2.name) return 1
else return 0
})
this._setStyleFromMirror(styleDecl)
return mirror
//-----------------------------------------------------------------------------
method _removePropertyFromMirror(mirror, index)
var properties = mirror.cssProperties
if (index >= properties.length) return
var property = properties[index]
properties[index] = null
if (mirror.shorthandValues[property.name]) {
delete mirror.shorthandValues[property.name]
for (var i=0; i<properties.length; i++) {
if (properties[i]) {
if (properties[i].shorthandName == property.name) {
properties[i] = null
}
}
}
}
var newProperties = []
for (var i=0; i<properties.length; i++) {
if (properties[i]) newProperties.push(properties[i])
}
mirror.cssProperties = newProperties
//-----------------------------------------------------------------------------
method toggleProperty(styleId, propertyIndex, disable)
var styleDecl = Weinre.cssStore._getStyleDecl(styleId)
if (!styleDecl) {
Weinre.logWarning("requested style not available: " + styleId)
return null
}
var mirror = styleDecl.__weinre__mirror
if (!mirror) {
Weinre.logWarning("requested mirror not available: " + styleId)
return null
}
var cssProperty = mirror.cssProperties[propertyIndex]
if (!cssProperty) {
Weinre.logWarning("requested property not available: " + styleId + ": " + propertyIndex)
return null
}
if (disable) {
cssProperty.status = "disabled"
}
else {
cssProperty.status = "active"
}
this._setStyleFromMirror(styleDecl)
return mirror
//-----------------------------------------------------------------------------
method _setStyleFromMirror(styleDecl)
var cssText = []
var cssProperties = styleDecl.__weinre__mirror.cssProperties
var cssText = ""
for (var i=0; i<cssProperties.length; i++) {
var property = cssProperties[i]
if (!property.parsedOk) continue
if (property.status == "disabled") continue
if (property.shorthandName) continue
cssText += property.name + ": " + property.value
if (property.priority == "important") {
cssText += " !important; "
}
else {
cssText += "; "
}
}
styleDecl.cssText = cssText
//-----------------------------------------------------------------------------
method _buildMirrorForStyle(styleDecl, bind)
var result = {
properties: {},
cssProperties: []
}
if (!styleDecl) return result
if (bind) {
result.styleId = this._getStyleDeclId(styleDecl)
styleDecl.__weinre__mirror = result
}
result.properties.width = styleDecl.getPropertyValue("width") || ""
result.properties.height = styleDecl.getPropertyValue("height") || ""
result.cssText = styleDecl.cssText
result.shorthandValues = {}
var properties = []
if (styleDecl) {
for (var i=0; i < styleDecl.length; i++) {
var property = {}
var name = styleDecl.item(i)
property.name = name
property.priority = styleDecl.getPropertyPriority(name)
property.implicit = styleDecl.isPropertyImplicit(name)
property.shorthandName = styleDecl.getPropertyShorthand(name) || ""
property.status = property.shorthandName ? "style" : "active"
property.parsedOk = true
property.value = styleDecl.getPropertyValue(name)
properties.push(property);
if (property.shorthandName) {
var shorthandName = property.shorthandName
if (!result.shorthandValues[shorthandName]) {
result.shorthandValues[shorthandName] = styleDecl.getPropertyValue(shorthandName)
property = {}
property.name = shorthandName
property.priority = styleDecl.getPropertyPriority(shorthandName)
property.implicit = styleDecl.isPropertyImplicit(shorthandName)
property.shorthandName = ""
property.status = "active"
property.parsedOk = true
property.value = styleDecl.getPropertyValue(name)
properties.push(property);
}
}
}
}
properties.sort(function(p1,p2) {
if (p1.name < p2.name) return -1
else if (p1.name > p2.name) return 1
else return 0
})
result.cssProperties = properties
return result
//-----------------------------------------------------------------------------
method _parseProperty(string)
var testStyleDecl = this.testElement.style
try {
testStyleDecl.cssText = string
if (testStyleDecl.cssText != "") {
return this._buildMirrorForStyle(testStyleDecl, false)
}
}
catch(e) {
}
var propertyPattern = /\s*(.+)\s*:\s*(.+)\s*(!important)?\s*;/
var match = propertyPattern.exec(string)
if (!match) return null
match[3] = (match[3] == "!important") ? "important" : ""
var property = {}
property.name = match[1]
property.priority = match[3]
property.implicit = true
property.shorthandName = ""
property.status = "inactive"
property.parsedOk = false
property.value = match[2]
var result = {}
result.width = 0
result.height = 0
result.shorthandValues = 0
result.cssProperties = [ property ]
return result
//-----------------------------------------------------------------------------
method _getStyleSheet(id)
return _getMappableObject(id, this.styleSheetMap)
//-----------------------------------------------------------------------------
method _getStyleSheetId(styleSheet)
return _getMappableId(styleSheet, this.styleSheetMap)
//-----------------------------------------------------------------------------
method _getStyleRule(id)
return _getMappableObject(id, this.styleRuleMap)
//-----------------------------------------------------------------------------
method _getStyleRuleId(styleRule)
return _getMappableId(styleRule, this.styleRuleMap)
//-----------------------------------------------------------------------------
method _getStyleDecl(id)
return _getMappableObject(id, this.styleDeclMap)
//-----------------------------------------------------------------------------
method _getStyleDeclId(styleDecl)
return _getMappableId(styleDecl, this.styleDeclMap)
//-----------------------------------------------------------------------------
function _getMappableObject(id, map)
return map[id]
//-----------------------------------------------------------------------------
function _getMappableId(object, map)
return IDGenerator.getId(object, map)
//-----------------------------------------------------------------------------
function _mozMatchesSelector(element, selector)
if (!element.mozMatchesSelector) return false
return element.mozMatchesSelector(selector)
//-----------------------------------------------------------------------------
function _webkitMatchesSelector(element, selector)
if (!element.webkitMatchesSelector) return false
return element.webkitMatchesSelector(selector)
//-----------------------------------------------------------------------------
function _fallbackMatchesSelector(element, selector)
return false
//-----------------------------------------------------------------------------
init
var _elementMatchesSelector
if (Element.prototype.webkitMatchesSelector) _elementMatchesSelector = _webkitMatchesSelector
else if (Element.prototype.mozMatchesSelector) _elementMatchesSelector = _mozMatchesSelector
else _elementMatchesSelector = _fallbackMatchesSelector