* Try to upgrade the element with the provided implementation. * @return {!Promise|undefined} * @private @final
()
| 1301 | * @private @final |
| 1302 | */ |
| 1303 | tryUpgrade_() { |
| 1304 | if (this.isInTemplate_) { |
| 1305 | return; |
| 1306 | } |
| 1307 | if (this.upgradeState_ != UpgradeState_Enum.NOT_UPGRADED) { |
| 1308 | // Already upgraded or in progress or failed. |
| 1309 | return; |
| 1310 | } |
| 1311 | |
| 1312 | const Ctor = devAssert( |
| 1313 | this.implClass_, |
| 1314 | 'Implementation must not be a stub' |
| 1315 | ); |
| 1316 | |
| 1317 | const impl = new Ctor(this); |
| 1318 | |
| 1319 | // The `upgradeCallback` only allows redirect once for the top-level |
| 1320 | // non-stub class. We may allow nested upgrades later, but they will |
| 1321 | // certainly be bad for performance. |
| 1322 | this.upgradeState_ = UpgradeState_Enum.UPGRADE_IN_PROGRESS; |
| 1323 | const startTime = win.Date.now(); |
| 1324 | const res = impl.upgradeCallback(); |
| 1325 | if (!res) { |
| 1326 | // Nothing returned: the current object is the upgraded version. |
| 1327 | this.completeUpgrade_(impl, startTime); |
| 1328 | } else if (typeof res.then == 'function') { |
| 1329 | // It's a promise: wait until it's done. |
| 1330 | return res |
| 1331 | .then((upgrade) => { |
| 1332 | this.completeUpgrade_(upgrade || impl, startTime); |
| 1333 | }) |
| 1334 | .catch((reason) => { |
| 1335 | this.upgradeState_ = UpgradeState_Enum.UPGRADE_FAILED; |
| 1336 | rethrowAsync(reason); |
| 1337 | }); |
| 1338 | } else { |
| 1339 | // It's an actual instance: upgrade immediately. |
| 1340 | this.completeUpgrade_( |
| 1341 | /** @type {!./base-element.BaseElement} */ (res), |
| 1342 | startTime |
| 1343 | ); |
| 1344 | } |
| 1345 | } |
| 1346 | |
| 1347 | /** |
| 1348 | * Called when the element is disconnected from the DOM. |
no test coverage detected