compatibility detector tool of chrome extensions
TRANSCRIPT
Compatibility Detector Tool of Chrome extensions
2011-05-07
Compatibility Detector Project
• Compatibility Detectorhttps://chrome.google.com/webstore/detail/fcillahbnhlpombgccogflhmgocfifma
• Source Codehttps://code.google.com/p/compatibility-detector/
Compatibility Detector scans for potential incompatible issues on a web page, for popular desktop browsers(IE, Firefox, Chrome, Opera, etc). The current version launch 14 detector.
Degree of project completion
• Check the actual document mode in browser
• Check CSS box model
• Check new block formatting context and IE hasLayout
• Check MARQUEE's element
• Check CENTER tag
• Check "disabled" attribute
• Check ': before' and ': after' pseudo-elements
• Check document.createElement method
• Check document.all
• ……
• the total number of about 30 completed, launch 14.
Objectives: Detection W3Help all compatibility root causes.
Chrome extensions
Extensions Features
• chrome.*API
• Cross-Origin XMLHttpReques
• Desktop Notification
• JavaScript and DOM API
• HTML5
– <canvas> <audio> <video> ……
– localStorage
– Web Database
– CSS 3
– CSS Selector
– ……
Working principle of extensions
Extension Process
Background Page
Popup Page
Other HTML Page
Page Process
Content Script
Page Script
Page DOM
Page Process
Content Script
Page Script
Page DOM
IPC
IPC
Content Script Process Model
Page Script Process
Page Script
C++ DOM
Object
append Global Context
V8 Global Context (EcmaScript Environment)
V8 Global Context (EcmaScript Environment)
ExtensionsDOMHandlerContent Script
Executio
n flo
w
Run DeferrerCan not Access
Content Script Process
Compatibility Detector
Compatibility Detector Files
• manifase.json
• background.html
• popup.html
• loader.js
• base_detection.js
• framework_shared.js
• framework.js
• detectors/*.js
Extension Process
ContentScript Context
Page Process
Page Script Context
Page Process
Message Model
DOM :: <HTML> <script> chrome_comp_injector () </script>
background.html
framewrok.js
page Script
Detectors/*.js
loader.js
run createElement
Inject to
psge Scrip
t
extension.sendRequestextension.onRequest
Popup.html Other HTML page
Cu
stom
Event d
ispatch
Even
tLis
ten
er
Page contentScript
framework_shared.js
framework_shared.js
Detector Model
• Class
– chrome_comp.CompDetect.declareDetector
– chrome_comp.CompDetect.ScanDomBaseDetector
– chrome_comp.CompDetect.NonScanDomBaseDetector
• Methods
– constructor
– checkNode
– postAnalyze
Detector Model
BaseDetector Class
NonScanDomBaseDetector Class
ScanDomBaseDetector Class
checkNode
addProblem
postAnalyze(empty)
constructor
postAnalyze
extend
extend
document.createNodeIterator for each Nodes
Detector Algorithm
Detector Algorithm
Detector Algorithm
JavaScript Hook Model
• chrome_comp. CompDetect .registerExistingMethodHook
• chrome_comp. CompDetect .registerExistingPropertyHook
Native Code
Detector Code
WrapSame Name
problemsContinue to other code
How to StartWrite Compatibility Detector Code
mainfest.json……"content_scripts": [{"matches": [ "http://*/*", "https://*/*", "file://*" ],"js": ["loader.js","framework.js","framework_shared.js","base_detection.js","config.js","w3help_issues.js","non_w3help_issues.js",
// Detector"detectors/ sample_check_node.js",
……
addScriptToInject(function() {
chrome_comp.CompDetect.declareDetector(
'sample_check_node',
chrome_comp.CompDetect.ScanDomBaseDetector,
function constructor() {
this.CHECK_TAG_NAME = {SPAN: true, DIV: true, TALBE: true};
this.addProblem = function (node) {
node.style.backgroundColor = 'red';
};
}, // constructor
function checkNode(node, context) {
if (Node.ELEMENT_NODE != node.nodeType || context.isDisplayNone())
return;
if (node.tagName in this.CHECK_TAG_NAME) {
if (node.hasAttribute('width') || node.hasAttribute('height'))
this.addProblem(node);
}
}
); // declareDetector
}); ScanDomBaseDetector checkNode
NonScanDomBaseDetector postAnalyze
addScriptToInject(function() {
chrome_comp.CompDetect.declareDetector(
'sample_post_analyze',
chrome_comp.CompDetect.NonScanDomBaseDetector,
null, // constructor
function postAnalyze() {
var m = chrome_comp.documentMode;
m.hasCommentBeforeDTD && log('There has Comment before DOCTYPE');
m.hasConditionalCommentBeforeDTD && log('There has IE conditional comment before DOCTYPE');
m.isUnusualDocType && log('There is unknown DOCTYPE');
(document.querySelectorAll('meta').length == 0) && log('This page has no Meta tag');
function log(str) {
var t = document.createTextNode(str),p = document.createElement('p');
p.appendChild(t);
document.body.appendChild(p);
}
}
); // declareDetector
});
addScriptToInject(function() {chrome_comp.CompDetect.declareDetector('sample_hook',chrome_comp.CompDetect.NonScanDomBaseDetector,function constructor() {var This = this;this.log = function(str) {
var t = document.createTextNode(str),p = document.createElement('p');p.appendChild(t);document.body.appendChild(p);
};
this.evalHandler_ = function (result, originalArguments, callStack) {if (originalArguments[0].indexOf('var ') == 0)window.addEventListener('load',function() {
This.log('Performed using the eval method ' + originalArguments[0] + 'statement.');},false)
};},function setUp() {chrome_comp.CompDetect.registerExistingMethodHook(window, 'eval', this.evalHandler_);
},function cleanUp() {chrome_comp.CompDetect.unregisterExistingMethodHook(window, 'eval', this.evalHandler_);
}); // declareDetector});
NonScanDomBaseDetector Method Hook
addScriptToInject(function() {chrome_comp.CompDetect.declareDetector('sample_hook_2',chrome_comp.CompDetect.NonScanDomBaseDetector,function constructor() {var This = this;this.log = function(str) {
var t = document.createTextNode(str),p = document.createElement('p');p.appendChild(t);document.body.appendChild(p);
};
this.handler_ = function(oldValue, newValue, reason) {if (reason == 'get') {This.log('Get document.documentMode value is ' + oldValue);
}if (reason == 'set') {This.log('Set document.documentMode value is ' + newValue);
}};
},function setUp() {chrome_comp.CompDetect.registerSimplePropertyHook(document, 'documentMode', this.handler_);
},function cleanUp() {chrome_comp.CompDetect.registerSimplePropertyHook(document, 'documentMode', this.handler_);
}); // declareDetector}); NonScanDomBaseDetector Property Hook
Multiplexing Detector Files
Build Your Own Test Framework
BaseDetector Class
NonScanDomBaseDetector Class
ScanDomBaseDetector Class
checkNode
addProblem
constructor
postAnalyze
WebKit Bot IE Bot
Browsers Bot
Your test framework
implementDetector Algorithm
Detector Algorithm
Detector Algorithm
Json
C++ String
PHP ...Local System
Browser API
Desktop app Web app
More accurate extract the contents in browsers Kernel
Compatibility Test Bot Demo
content-type:problems:[{"id":"RM8002","info":{"repeatedCount":6,"occurrences":[{"details":"Problem Element height is 38px","html":["<div id=\"div1\" style=\"zoom:1;\" expectedproblems=\"RM8002\">\n div1 zoom:1;\n <div style=\"float:left;\">div float:left;</div>\n <div style=\"float:right;\">div float:right;</div>\n</div>","<div style=\"float:left;\">div float:left;</div>"],"stack":""},{"details":"Problem Element height is 16px","html":["<div id=\"div5\" style=\"height:1em;\" expectedproblems=\"RM8002\">\n div5 height:1em;\n <div style=\"float:left;\">div float:left;</div>\n <div style=\"float:right;\">div float:right;</div>\n</div>","<div style=\"float:left;\">div float:left;</div>"],"stack":""}……
D:\ProgramData\Windows\Desktop\demo>Detect.exe --url=clear_float.html
Q&AMark huang, Google Chrome team
FinishedThanks