| Index: chrome/content/composer.js | 
| =================================================================== | 
| --- a/chrome/content/composer.js | 
| +++ b/chrome/content/composer.js | 
| @@ -14,61 +14,16 @@ let treeView = null; | 
| let stylesheetData; | 
| let previewStyle = null; | 
| let doc; | 
|  | 
| let abpURL = Cc["@adblockplus.org/abp/public;1"].getService(Ci.nsIURI); | 
| Cu.import(abpURL.spec); | 
|  | 
| /******************* | 
| - * NodeData object * | 
| - *******************/ | 
| - | 
| -function NodeData(node, parentNode) { | 
| -  this.tagName = {value: node.tagName, checked: false}; | 
| - | 
| -  if (typeof parentNode == "undefined") | 
| -    parentNode = (node.parentNode && node.parentNode.nodeType == node.ELEMENT_NODE ? new NodeData(node.parentNode) : null); | 
| -  this.parentNode = parentNode; | 
| - | 
| -  var prevSibling = node.previousSibling; | 
| -  while (prevSibling && prevSibling.nodeType != node.ELEMENT_NODE) | 
| -    prevSibling = prevSibling.previousSibling; | 
| -  this.prevSibling = (prevSibling ? new NodeData(prevSibling, this.parentNode) : null); | 
| - | 
| -  if (parentNode && !prevSibling) | 
| -    this.firstChild = {checked: false}; | 
| - | 
| -  var nextSibling = node.nextSibling; | 
| -  while (nextSibling && nextSibling.nodeType != node.ELEMENT_NODE) | 
| -    nextSibling = nextSibling.nextSibling; | 
| -  if (parentNode && !nextSibling) | 
| -    this.lastChild = {checked: false}; | 
| - | 
| -  this.attributes = []; | 
| -  for (var i = 0; i < node.attributes.length; i++) { | 
| -    var attribute = node.attributes[i]; | 
| -    var data = {name: attribute.name, value: attribute.value, selected: attribute.value, checked: false}; | 
| -    if (data.name == "id" || data.name == "class") | 
| -      this.attributes.unshift(data); | 
| -    else | 
| -      this.attributes.push(data); | 
| -  } | 
| - | 
| -  if (this.attributes.length >= 2 && this.attributes[1].name == "id") { | 
| -    // Make sure ID attribute comes first | 
| -    var tmp = this.attributes[1]; | 
| -    this.attributes[1] = this.attributes[0]; | 
| -    this.attributes[0] = tmp; | 
| -  } | 
| - | 
| -  this.customCSS = {selected: "", checked: false}; | 
| -} | 
| - | 
| -/******************* | 
| * TreeView object * | 
| *******************/ | 
|  | 
| function TreeView(tree) { | 
| var origView = tree.view; | 
| this.getRowProperties = TreeView_getRowProperties; | 
| this.getCellProperties = TreeView_getCellProperties; | 
|  | 
| @@ -122,32 +77,31 @@ function TreeView_getRowProperties(row) | 
| function TreeView_getCellProperties(row, col) { | 
| this.getRowProperties(row); | 
| } | 
|  | 
| /********************* | 
| * General functions * | 
| *********************/ | 
|  | 
| -function init() { | 
| -  var element = window.arguments[0]; | 
| -  doc = element.ownerDocument; | 
| -  var wnd = doc.defaultView; | 
| +function init() | 
| +{ | 
| +  nodeData = window.arguments[0]; | 
| +  let host = window.arguments[1]; | 
|  | 
| // Check whether element hiding group is disabled | 
| let subscription = AdblockPlus.getSubscription("~eh~"); | 
| if (subscription && subscription.disabled) | 
| { | 
| let warning = document.getElementById("groupDisabledWarning"); | 
| if (/\?1\?/.test(warning.textContent)) | 
| warning.textContent = warning.textContent.replace(/\?1\?/g, subscription.title); | 
| warning.hidden = false; | 
| } | 
|  | 
| -  nodeData = new NodeData(element); | 
| nodeData.tagName.checked = true; | 
| if (nodeData.attributes.length > 0) | 
| { | 
| let maxLen = 0; | 
| let bestAttr = null; | 
| for (let i = 0; i < nodeData.attributes.length; i++) | 
| { | 
| let len = nodeData.attributes[i].value.length; | 
| @@ -164,47 +118,46 @@ function init() { | 
| } | 
| if (bestAttr) | 
| { | 
| bestAttr.selected = bestAttr.value; | 
| bestAttr.checked = true; | 
| } | 
| } | 
|  | 
| -  let domain = wnd.location.hostname; | 
| let selectedDomain; | 
| switch (Prefs.composer_defaultDomain) | 
| { | 
| case 0: | 
| selectedDomain = ""; | 
| break; | 
| case 1: | 
| try | 
| { | 
| // EffectiveTLDService will throw for IP addresses, just go to the next case then | 
| let effectiveTLD = Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci.nsIEffectiveTLDService); | 
| -        selectedDomain = effectiveTLD.getPublicSuffixFromHost(domain); | 
| +        selectedDomain = effectiveTLD.getPublicSuffixFromHost(host); | 
| break; | 
| } catch (e) {} | 
| case 2: | 
| try | 
| { | 
| // EffectiveTLDService will throw for IP addresses, just go to the next case then | 
| let effectiveTLD = Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci.nsIEffectiveTLDService); | 
| -        selectedDomain = effectiveTLD.getBaseDomainFromHost(domain); | 
| +        selectedDomain = effectiveTLD.getBaseDomainFromHost(host); | 
| break; | 
| } catch (e) {} | 
| case 3: | 
| -      selectedDomain = domain.replace(/^www\./, ""); | 
| +      selectedDomain = host.replace(/^www\./, ""); | 
| break; | 
| default: | 
| -      selectedDomain = domain; | 
| +      selectedDomain = host; | 
| break; | 
| } | 
| -  domainData = {value: domain, selected: selectedDomain}; | 
| +  domainData = {value: host, selected: selectedDomain}; | 
|  | 
| fillDomains(domainData); | 
| fillNodes(nodeData); | 
| setAdvancedMode(document.documentElement.getAttribute("advancedMode") == "true"); | 
| updateExpression(); | 
|  | 
| setTimeout(function() { | 
| document.getElementById("domainGroup").selectedItem.focus(); | 
| @@ -237,17 +190,17 @@ function updateExpression() | 
| { | 
| var op = "*="; | 
| if (attr.selected == attr.value) | 
| op = "="; | 
| else if (attr.value.substr(0, attr.selected.length) == attr.selected) | 
| op = "^="; | 
| else if (attr.value.substr(attr.value.length - attr.selected.length) == attr.selected) | 
| op = "$="; | 
| - | 
| + | 
| let useFallback = false; | 
| if (attr.name == "id" && op == "=") | 
| expression += "#" + escapeName(attr.selected).replace(/^([^a-zA-Z\\])/, escapeChar).replace(/\\(\s)$/, escapeChar); | 
| else if (attr.name == "class" && /\S/.test(attr.selected)) | 
| { | 
| let knownClasses = new Set(attr.value.split(/\s+/)); | 
| let classes = attr.selected.split(/\s+/).filter(cls => cls != ""); | 
| if (classes.every(cls => knownClasses.has(cls))) | 
|  |