| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * This configuration can be used to rerun selected tests, as well | 6 * This configuration can be used to rerun selected tests, as well |
| 7 * as see diagnostic output from tests. It runs each test in its own | 7 * as see diagnostic output from tests. It runs each test in its own |
| 8 * IFrame, so the configuration consists of two parts - a 'master' | 8 * IFrame, so the configuration consists of two parts - a 'parent' |
| 9 * config that manages all the tests, and a 'slave' config for the | 9 * config that manages all the tests, and a 'child' config for the |
| 10 * IFrame that runs the individual tests. | 10 * IFrame that runs the individual tests. |
| 11 */ | 11 */ |
| 12 #library('interactive_config'); | 12 #library('interactive_config'); |
| 13 | 13 |
| 14 // TODO(gram) - add options for: remove IFrame on done/keep | 14 // TODO(gram) - add options for: remove IFrame on done/keep |
| 15 // IFrame for failed tests/keep IFrame for all tests. | 15 // IFrame for failed tests/keep IFrame for all tests. |
| 16 | 16 |
| 17 #import('dart:html'); | 17 #import('dart:html'); |
| 18 #import('dart:math'); | 18 #import('dart:math'); |
| 19 #import('unittest.dart'); | 19 #import('unittest.dart'); |
| 20 | 20 |
| 21 /** The messages exchanged between master and slave. */ | 21 /** The messages exchanged between parent and child. */ |
| 22 | 22 |
| 23 class _Message { | 23 class _Message { |
| 24 static const START = 'start'; | 24 static const START = 'start'; |
| 25 static const LOG = 'log'; | 25 static const LOG = 'log'; |
| 26 static const STACK = 'stack'; | 26 static const STACK = 'stack'; |
| 27 static const PASS = 'pass'; | 27 static const PASS = 'pass'; |
| 28 static const FAIL = 'fail'; | 28 static const FAIL = 'fail'; |
| 29 static const ERROR = 'error'; | 29 static const ERROR = 'error'; |
| 30 | 30 |
| 31 String messageType; | 31 String messageType; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 45 int idx2 = msg.indexOf(' ', idx); | 45 int idx2 = msg.indexOf(' ', idx); |
| 46 elapsed = parseInt(msg.substring(idx, idx2)); | 46 elapsed = parseInt(msg.substring(idx, idx2)); |
| 47 ++idx2; | 47 ++idx2; |
| 48 body = msg.substring(idx2); | 48 body = msg.substring(idx2); |
| 49 } | 49 } |
| 50 | 50 |
| 51 String toString() => text(messageType, elapsed, body); | 51 String toString() => text(messageType, elapsed, body); |
| 52 } | 52 } |
| 53 | 53 |
| 54 /** | 54 /** |
| 55 * The slave configuration that is used to run individual tests in | 55 * The child configuration that is used to run individual tests in |
| 56 * an IFrame and post the results back to the master. In principle | 56 * an IFrame and post the results back to the parent. In principle |
| 57 * this can run more than one test in the IFrame but currently only | 57 * this can run more than one test in the IFrame but currently only |
| 58 * one is used. | 58 * one is used. |
| 59 */ | 59 */ |
| 60 class SlaveInteractiveHtmlConfiguration extends Configuration { | 60 class ChildInteractiveHtmlConfiguration extends Configuration { |
| 61 // TODO(rnystrom): Get rid of this if we get canonical closures for methods. | 61 // TODO(rnystrom): Get rid of this if we get canonical closures for methods. |
| 62 EventListener _onErrorClosure; | 62 EventListener _onErrorClosure; |
| 63 | 63 |
| 64 /** The window to which results must be posted. */ | 64 /** The window to which results must be posted. */ |
| 65 Window masterWindow; | 65 Window parentWindow; |
| 66 | 66 |
| 67 /** The time at which tests start. */ | 67 /** The time at which tests start. */ |
| 68 Map<int,Date> _testStarts; | 68 Map<int,Date> _testStarts; |
| 69 | 69 |
| 70 SlaveInteractiveHtmlConfiguration() : | 70 ChildInteractiveHtmlConfiguration() : |
| 71 _testStarts = new Map<int,Date>(); | 71 _testStarts = new Map<int,Date>(); |
| 72 | 72 |
| 73 /** Don't start running tests automatically. */ | 73 /** Don't start running tests automatically. */ |
| 74 get autoStart() => false; | 74 get autoStart => false; |
| 75 | 75 |
| 76 void onInit() { | 76 void onInit() { |
| 77 _onErrorClosure = | 77 _onErrorClosure = |
| 78 (e) => handleExternalError(e, '(DOM callback has errors)'); | 78 (e) => handleExternalError(e, '(DOM callback has errors)'); |
| 79 | 79 |
| 80 /** | 80 /** |
| 81 * The master posts a 'start' message to kick things off, | 81 * The parent posts a 'start' message to kick things off, |
| 82 * which is handled by this handler. It saves the master | 82 * which is handled by this handler. It saves the parent |
| 83 * window, gets the test ID from the query parameter in the | 83 * window, gets the test ID from the query parameter in the |
| 84 * IFrame URL, sets that as a solo test and starts test execution. | 84 * IFrame URL, sets that as a solo test and starts test execution. |
| 85 */ | 85 */ |
| 86 window.on.message.add((MessageEvent e) { | 86 window.on.message.add((MessageEvent e) { |
| 87 // Get the result, do any logging, then do a pass/fail. | 87 // Get the result, do any logging, then do a pass/fail. |
| 88 var m = new _Message.fromString(e.data); | 88 var m = new _Message.fromString(e.data); |
| 89 if (m.messageType == _Message.START) { | 89 if (m.messageType == _Message.START) { |
| 90 masterWindow = e.source; | 90 parentWindow = e.source; |
| 91 String search = window.location.search; | 91 String search = window.location.search; |
| 92 int pos = search.indexOf('t='); | 92 int pos = search.indexOf('t='); |
| 93 String ids = search.substring(pos+2); | 93 String ids = search.substring(pos+2); |
| 94 int id = parseInt(ids); | 94 int id = parseInt(ids); |
| 95 setSoloTest(id); | 95 setSoloTest(id); |
| 96 runTests(); | 96 runTests(); |
| 97 } | 97 } |
| 98 }); | 98 }); |
| 99 } | 99 } |
| 100 | 100 |
| 101 void onStart() { | 101 void onStart() { |
| 102 // Listen for uncaught errors. | 102 // Listen for uncaught errors. |
| 103 window.on.error.add(_onErrorClosure); | 103 window.on.error.add(_onErrorClosure); |
| 104 } | 104 } |
| 105 | 105 |
| 106 /** Record the start time of the test. */ | 106 /** Record the start time of the test. */ |
| 107 void onTestStart(TestCase testCase) { | 107 void onTestStart(TestCase testCase) { |
| 108 super.onTestStart(testCase); | 108 super.onTestStart(testCase); |
| 109 _testStarts[testCase.id]= new Date.now(); | 109 _testStarts[testCase.id]= new Date.now(); |
| 110 } | 110 } |
| 111 | 111 |
| 112 /** | 112 /** |
| 113 * Tests can call [log] for diagnostic output. These log | 113 * Tests can call [logMessage] for diagnostic output. These log |
| 114 * messages in turn get passed to this method, which adds | 114 * messages in turn get passed to this method, which adds |
| 115 * a timestamp and posts them back to the master window. | 115 * a timestamp and posts them back to the parent window. |
| 116 */ | 116 */ |
| 117 void logMessage(TestCase testCase, String message) { | 117 void logTestCaseMessage(TestCase testCase, String message) { |
| 118 int elapsed; | 118 int elapsed; |
| 119 if (testCase == null) { | 119 if (testCase == null) { |
| 120 elapsed = -1; | 120 elapsed = -1; |
| 121 } else { | 121 } else { |
| 122 Date end = new Date.now(); | 122 Date end = new Date.now(); |
| 123 elapsed = end.difference(_testStarts[testCase.id]).inMilliseconds; | 123 elapsed = end.difference(_testStarts[testCase.id]).inMilliseconds; |
| 124 } | 124 } |
| 125 masterWindow.postMessage( | 125 parentWindow.postMessage( |
| 126 _Message.text(_Message.LOG, elapsed, message).toString(), '*'); | 126 _Message.text(_Message.LOG, elapsed, message).toString(), '*'); |
| 127 } | 127 } |
| 128 | 128 |
| 129 /** | 129 /** |
| 130 * Get the elapsed time for the test, anbd post the test result | 130 * Get the elapsed time for the test, anbd post the test result |
| 131 * back to the master window. If the test failed due to an exception | 131 * back to the parent window. If the test failed due to an exception |
| 132 * the stack is posted back too (before the test result). | 132 * the stack is posted back too (before the test result). |
| 133 */ | 133 */ |
| 134 void onTestResult(TestCase testCase) { | 134 void onTestResult(TestCase testCase) { |
| 135 super.onTestResult(testCase); | 135 super.onTestResult(testCase); |
| 136 Date end = new Date.now(); | 136 Date end = new Date.now(); |
| 137 int elapsed = end.difference(_testStarts[testCase.id]).inMilliseconds; | 137 int elapsed = end.difference(_testStarts[testCase.id]).inMilliseconds; |
| 138 if (testCase.stackTrace != null) { | 138 if (testCase.stackTrace != null) { |
| 139 masterWindow.postMessage( | 139 parentWindow.postMessage( |
| 140 _Message.text(_Message.STACK, elapsed, testCase.stackTrace), '*'); | 140 _Message.text(_Message.STACK, elapsed, testCase.stackTrace), '*'); |
| 141 } | 141 } |
| 142 masterWindow.postMessage( | 142 parentWindow.postMessage( |
| 143 _Message.text(testCase.result, elapsed, testCase.message), '*'); | 143 _Message.text(testCase.result, elapsed, testCase.message), '*'); |
| 144 } | 144 } |
| 145 | 145 |
| 146 void onDone(int passed, int failed, int errors, List<TestCase> results, | 146 void onDone(int passed, int failed, int errors, List<TestCase> results, |
| 147 String uncaughtError) { | 147 String uncaughtError) { |
| 148 window.on.error.remove(_onErrorClosure); | 148 window.on.error.remove(_onErrorClosure); |
| 149 } | 149 } |
| 150 } | 150 } |
| 151 | 151 |
| 152 /** | 152 /** |
| 153 * The master configuration runs in the top-level window; it wraps the tests | 153 * The parent configuration runs in the top-level window; it wraps the tests |
| 154 * in new functions that create slave IFrames and run the real tests. | 154 * in new functions that create child IFrames and run the real tests. |
| 155 */ | 155 */ |
| 156 class MasterInteractiveHtmlConfiguration extends Configuration { | 156 class ParentInteractiveHtmlConfiguration extends Configuration { |
| 157 Map<int,Date> _testStarts; | 157 Map<int,Date> _testStarts; |
| 158 // TODO(rnystrom): Get rid of this if we get canonical closures for methods. | 158 // TODO(rnystrom): Get rid of this if we get canonical closures for methods. |
| 159 EventListener _onErrorClosure; | 159 EventListener _onErrorClosure; |
| 160 | 160 |
| 161 /** The stack that was posted back from the slave, if any. */ | 161 /** The stack that was posted back from the child, if any. */ |
| 162 String _stack; | 162 String _stack; |
| 163 | 163 |
| 164 int _testTime; | 164 int _testTime; |
| 165 /** | 165 /** |
| 166 * Whether or not we have already wrapped the TestCase test functions | 166 * Whether or not we have already wrapped the TestCase test functions |
| 167 * in new closures that instead create an IFrame and get it to run the | 167 * in new closures that instead create an IFrame and get it to run the |
| 168 * test. | 168 * test. |
| 169 */ | 169 */ |
| 170 bool _doneWrap = false; | 170 bool _doneWrap = false; |
| 171 | 171 |
| 172 /** | 172 /** |
| 173 * We use this to make a single closure from _handleMessage so we | 173 * We use this to make a single closure from _handleMessage so we |
| 174 * can remove the handler later. | 174 * can remove the handler later. |
| 175 */ | 175 */ |
| 176 Function _messageHandler; | 176 Function _messageHandler; |
| 177 | 177 |
| 178 MasterInteractiveHtmlConfiguration() : | 178 ParentInteractiveHtmlConfiguration() : |
| 179 _testStarts = new Map<int,Date>(); | 179 _testStarts = new Map<int,Date>(); |
| 180 | 180 |
| 181 // We need to block until the test is done, so we make a | 181 // We need to block until the test is done, so we make a |
| 182 // dummy async callback that we will use to flag completion. | 182 // dummy async callback that we will use to flag completion. |
| 183 Function completeTest = null; | 183 Function completeTest = null; |
| 184 | 184 |
| 185 wrapTest(TestCase testCase) { | 185 wrapTest(TestCase testCase) { |
| 186 String baseUrl = window.location.toString(); | 186 String baseUrl = window.location.toString(); |
| 187 String url = '${baseUrl}?t=${testCase.id}'; | 187 String url = '${baseUrl}?t=${testCase.id}'; |
| 188 return () { | 188 return () { |
| 189 // Rebuild the slave IFrame. | 189 // Rebuild the child IFrame. |
| 190 Element slaveDiv = document.query('#slave'); | 190 Element childDiv = document.query('#child'); |
| 191 slaveDiv.nodes.clear(); | 191 childDiv.nodes.clear(); |
| 192 IFrameElement slave = new Element.html(""" | 192 IFrameElement child = new Element.html(""" |
| 193 <iframe id='slaveFrame${testCase.id}' src='$url' style='display:none'> | 193 <iframe id='childFrame${testCase.id}' src='$url' style='display:none'> |
| 194 </iframe>"""); | 194 </iframe>"""); |
| 195 slaveDiv.nodes.add(slave); | 195 childDiv.nodes.add(child); |
| 196 completeTest = expectAsync0((){ }); | 196 completeTest = expectAsync0((){ }); |
| 197 // Kick off the test when the IFrame is loaded. | 197 // Kick off the test when the IFrame is loaded. |
| 198 slave.on.load.add((e) { | 198 child.on.load.add((e) { |
| 199 slave.contentWindow.postMessage(_Message.text(_Message.START), '*'); | 199 child.contentWindow.postMessage(_Message.text(_Message.START), '*'); |
| 200 }); | 200 }); |
| 201 }; | 201 }; |
| 202 } | 202 } |
| 203 | 203 |
| 204 void _handleMessage(MessageEvent e) { | 204 void _handleMessage(MessageEvent e) { |
| 205 // Get the result, do any logging, then do a pass/fail. | 205 // Get the result, do any logging, then do a pass/fail. |
| 206 var msg = new _Message.fromString(e.data); | 206 var msg = new _Message.fromString(e.data); |
| 207 if (msg.messageType == _Message.LOG) { | 207 if (msg.messageType == _Message.LOG) { |
| 208 log(e.data); | 208 logMessage(e.data); |
| 209 } else if (msg.messageType == _Message.STACK) { | 209 } else if (msg.messageType == _Message.STACK) { |
| 210 _stack = msg.body; | 210 _stack = msg.body; |
| 211 } else { | 211 } else { |
| 212 _testTime = msg.elapsed; | 212 _testTime = msg.elapsed; |
| 213 log(_Message.text(_Message.LOG, _testTime, 'Complete')); | 213 logMessage(_Message.text(_Message.LOG, _testTime, 'Complete')); |
| 214 if (msg.messageType == _Message.PASS) { | 214 if (msg.messageType == _Message.PASS) { |
| 215 currentTestCase.pass(); | 215 currentTestCase.pass(); |
| 216 } else if (msg.messageType == _Message.FAIL) { | 216 } else if (msg.messageType == _Message.FAIL) { |
| 217 currentTestCase.fail(msg.body, _stack); | 217 currentTestCase.fail(msg.body, _stack); |
| 218 } else if (msg.messageType == _Message.ERROR) { | 218 } else if (msg.messageType == _Message.ERROR) { |
| 219 currentTestCase.error(msg.body, _stack); | 219 currentTestCase.error(msg.body, _stack); |
| 220 } | 220 } |
| 221 completeTest(); | 221 completeTest(); |
| 222 } | 222 } |
| 223 } | 223 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 <ul class='tests'> | 279 <ul class='tests'> |
| 280 </ul> | 280 </ul> |
| 281 </div>"""); | 281 </div>"""); |
| 282 document.query('#group-divs').nodes.add(groupDiv); | 282 document.query('#group-divs').nodes.add(groupDiv); |
| 283 groupDiv.query('.groupselect').on.click.add((e) { | 283 groupDiv.query('.groupselect').on.click.add((e) { |
| 284 var parent = document.query('#$groupId'); | 284 var parent = document.query('#$groupId'); |
| 285 InputElement cb = parent.query('.groupselect'); | 285 InputElement cb = parent.query('.groupselect'); |
| 286 var state = cb.checked; | 286 var state = cb.checked; |
| 287 var tests = parent.query('.tests'); | 287 var tests = parent.query('.tests'); |
| 288 for (Element t in tests.elements) { | 288 for (Element t in tests.elements) { |
| 289 cb = t.query('.testselect'); | 289 cb = t.query('.testselect') as InputElement; |
| 290 cb.checked = state; | 290 cb.checked = state; |
| 291 var testId = parseInt(t.id.substring(_testIdPrefix.length)); | 291 var testId = parseInt(t.id.substring(_testIdPrefix.length)); |
| 292 if (state) { | 292 if (state) { |
| 293 enableTest(testId); | 293 enableTest(testId); |
| 294 } else { | 294 } else { |
| 295 disableTest(testId); | 295 disableTest(testId); |
| 296 } | 296 } |
| 297 } | 297 } |
| 298 }); | 298 }); |
| 299 } | 299 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 } | 337 } |
| 338 }); | 338 }); |
| 339 } else { // Reset the test element. | 339 } else { // Reset the test element. |
| 340 testItem.classes.clear(); | 340 testItem.classes.clear(); |
| 341 testItem.classes.add('test-it'); | 341 testItem.classes.add('test-it'); |
| 342 testItem.classes.add('status-pending'); | 342 testItem.classes.add('status-pending'); |
| 343 testItem.query('#$_actionIdPrefix$id').innerHTML = ''; | 343 testItem.query('#$_actionIdPrefix$id').innerHTML = ''; |
| 344 } | 344 } |
| 345 } | 345 } |
| 346 | 346 |
| 347 // Actually test logging is handled by the slave, then posted | 347 // Actually test logging is handled by the child, then posted |
| 348 // back to the master. So here we know that the [message] argument | 348 // back to the parent. So here we know that the [message] argument |
| 349 // is in the format used by [_Message]. | 349 // is in the format used by [_Message]. |
| 350 void logMessage(TestCase testCase, String message) { | 350 void logTestCaseMessage(TestCase testCase, String message) { |
| 351 var msg = new _Message.fromString(message); | 351 var msg = new _Message.fromString(message); |
| 352 if (msg.elapsed < 0) { // No associated test case. | 352 if (msg.elapsed < 0) { // No associated test case. |
| 353 document.query('#otherlogs').nodes.add( | 353 document.query('#otherlogs').nodes.add( |
| 354 new Element.html('<p>${msg.body}</p>')); | 354 new Element.html('<p>${msg.body}</p>')); |
| 355 } else { | 355 } else { |
| 356 var actions = document.query('#$_testIdPrefix${testCase.id}'). | 356 var actions = document.query('#$_testIdPrefix${testCase.id}'). |
| 357 query('.test-actions'); | 357 query('.test-actions'); |
| 358 String elapsedText = msg.elapsed >= 0 ? "${msg.elapsed}ms" : ""; | 358 String elapsedText = msg.elapsed >= 0 ? "${msg.elapsed}ms" : ""; |
| 359 actions.nodes.add(new Element.html( | 359 actions.nodes.add(new Element.html( |
| 360 "<li style='list-style-stype:none>" | 360 "<li style='list-style-stype:none>" |
| 361 "<div class='timer-result'>${elapsedText}</div>" | 361 "<div class='timer-result'>${elapsedText}</div>" |
| 362 "<div class='test-title'>${msg.body}</div>" | 362 "<div class='test-title'>${msg.body}</div>" |
| 363 "</li>")); | 363 "</li>")); |
| 364 } | 364 } |
| 365 } | 365 } |
| 366 | 366 |
| 367 void onTestResult(TestCase testCase) { | 367 void onTestResult(TestCase testCase) { |
| 368 if (!testCase.enabled) return; | 368 if (!testCase.enabled) return; |
| 369 super.onTestResult(testCase); | 369 super.onTestResult(testCase); |
| 370 if (testCase.message != '') { | 370 if (testCase.message != '') { |
| 371 logMessage(testCase, _Message.text(_Message.LOG, -1, testCase.message)); | 371 logTestCaseMessage(testCase, |
| 372 _Message.text(_Message.LOG, -1, testCase.message)); |
| 372 } | 373 } |
| 373 int id = testCase.id; | 374 int id = testCase.id; |
| 374 var testItem = document.query('#$_testIdPrefix$id'); | 375 var testItem = document.query('#$_testIdPrefix$id'); |
| 375 var timeSpan = testItem.query('.test-timer-result'); | 376 var timeSpan = testItem.query('.test-timer-result'); |
| 376 timeSpan.text = '${_testTime}ms'; | 377 timeSpan.text = '${_testTime}ms'; |
| 377 // Convert status into what we need for our CSS. | 378 // Convert status into what we need for our CSS. |
| 378 String result = 'status-error'; | 379 String result = 'status-error'; |
| 379 if (testCase.result == 'pass') { | 380 if (testCase.result == 'pass') { |
| 380 result = 'status-success'; | 381 result = 'status-success'; |
| 381 } else if (testCase.result == 'fail') { | 382 } else if (testCase.result == 'fail') { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 397 window.on.error.remove(_onErrorClosure); | 398 window.on.error.remove(_onErrorClosure); |
| 398 document.query('#busy').style.display = 'none'; | 399 document.query('#busy').style.display = 'none'; |
| 399 InputElement startButton = document.query('#start'); | 400 InputElement startButton = document.query('#start'); |
| 400 startButton.disabled = false; | 401 startButton.disabled = false; |
| 401 } | 402 } |
| 402 } | 403 } |
| 403 | 404 |
| 404 /** | 405 /** |
| 405 * Add the divs to the DOM if they are not present. We have a 'controls' | 406 * Add the divs to the DOM if they are not present. We have a 'controls' |
| 406 * div for control, 'specs' div with test results, a 'busy' div for the | 407 * div for control, 'specs' div with test results, a 'busy' div for the |
| 407 * animated GIF used to indicate tests are running, and a 'slave' div to | 408 * animated GIF used to indicate tests are running, and a 'child' div to |
| 408 * hold the iframe for the test. | 409 * hold the iframe for the test. |
| 409 */ | 410 */ |
| 410 void _prepareDom() { | 411 void _prepareDom() { |
| 411 if (document.query('#control') == null) { | 412 if (document.query('#control') == null) { |
| 412 // Use this as an opportunity for adding the CSS too. | 413 // Use this as an opportunity for adding the CSS too. |
| 413 // I wanted to avoid having to include a css element explicitly | 414 // I wanted to avoid having to include a css element explicitly |
| 414 // in the main html file. I considered moving all the styles | 415 // in the main html file. I considered moving all the styles |
| 415 // inline as attributes but that started getting very messy, | 416 // inline as attributes but that started getting very messy, |
| 416 // so we do it this way. | 417 // so we do it this way. |
| 417 document.body.nodes.add(new Element.html("<style>$_CSS</style>")); | 418 document.body.nodes.add(new Element.html("<style>$_CSS</style>")); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 431 } | 432 } |
| 432 if (document.query('#specs') == null) { | 433 if (document.query('#specs') == null) { |
| 433 document.body.nodes.add(new Element.html( | 434 document.body.nodes.add(new Element.html( |
| 434 "<div id='specs'><div id='group-divs'></div></div>")); | 435 "<div id='specs'><div id='group-divs'></div></div>")); |
| 435 } | 436 } |
| 436 if (document.query('#busy') == null) { | 437 if (document.query('#busy') == null) { |
| 437 document.body.nodes.add(new Element.html( | 438 document.body.nodes.add(new Element.html( |
| 438 "<div id='busy' style='display:none'><img src='googleballs.gif'>" | 439 "<div id='busy' style='display:none'><img src='googleballs.gif'>" |
| 439 "</img></div>")); | 440 "</img></div>")); |
| 440 } | 441 } |
| 441 if (document.query('#slave') == null) { | 442 if (document.query('#child') == null) { |
| 442 document.body.nodes.add(new Element.html("<div id='slave'></div>")); | 443 document.body.nodes.add(new Element.html("<div id='child'></div>")); |
| 443 } | 444 } |
| 444 } | 445 } |
| 445 | 446 |
| 446 /** | 447 /** |
| 447 * Allocate a Configuration. We allocate either a master or | 448 * Allocate a Configuration. We allocate either a parent or |
| 448 * slave, depedning on whether the URL has a search part. | 449 * child, depedning on whether the URL has a search part. |
| 449 */ | 450 */ |
| 450 void useInteractiveHtmlConfiguration() { | 451 void useInteractiveHtmlConfiguration() { |
| 451 if (window.location.search == '') { // This is the master. | 452 if (window.location.search == '') { // This is the parent. |
| 452 _prepareDom(); | 453 _prepareDom(); |
| 453 configure(new MasterInteractiveHtmlConfiguration()); | 454 configure(new ParentInteractiveHtmlConfiguration()); |
| 454 } else { | 455 } else { |
| 455 configure(new SlaveInteractiveHtmlConfiguration()); | 456 configure(new ChildInteractiveHtmlConfiguration()); |
| 456 } | 457 } |
| 457 } | 458 } |
| 458 | 459 |
| 459 String _CSS = """ | 460 String _CSS = """ |
| 460 body { | 461 body { |
| 461 font-family: Arial, sans-serif; | 462 font-family: Arial, sans-serif; |
| 462 margin: 0; | 463 margin: 0; |
| 463 font-size: 14px; | 464 font-size: 14px; |
| 464 } | 465 } |
| 465 | 466 |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 display: block; | 649 display: block; |
| 649 list-style-type: disc; | 650 list-style-type: disc; |
| 650 -webkit-margin-before: 1em; | 651 -webkit-margin-before: 1em; |
| 651 -webkit-margin-after: 1em; | 652 -webkit-margin-after: 1em; |
| 652 -webkit-margin-start: 0px; | 653 -webkit-margin-start: 0px; |
| 653 -webkit-margin-end: 0px; | 654 -webkit-margin-end: 0px; |
| 654 -webkit-padding-start: 40px; | 655 -webkit-padding-start: 40px; |
| 655 } | 656 } |
| 656 | 657 |
| 657 """; | 658 """; |
| OLD | NEW |