58 Commits
Author SHA1 Message Date
Andrey Savchenko 4b7ee062c8 Updated change log and version for release 1.4.1. 2016-12-01 20:35:19 +02:00
Andrey Savchenko 2e7a948bfe Added access modifier to methods. 2016-12-01 20:34:15 +02:00
Andrey Savchenko 68ae657962 Added check for Toolbar event start before closing it. 2016-12-01 20:33:55 +02:00
Andrey Savchenko 3edaf2dbc9 Added check for hook priority failing on WP 4.7. 2016-12-01 20:30:48 +02:00
Andrey Savchenko fa155f00e7 Fixed return type hint. 2016-12-01 20:30:15 +02:00
Andrey Savchenko 82b3d1e4e3 Moved license to a separate file. 2016-12-01 20:29:52 +02:00
Andrey Savchenko 0984debd79 Release 1.4 2016-10-01 20:17:36 +03:00
Andrey Savchenko 2ddbd04b29 Colorized SQL writes as warnings. 2016-10-01 20:16:17 +03:00
Andrey Savchenko a16eebd026 Corrected change log heading markup. 2016-10-01 15:34:47 +03:00
Andrey Savchenko 274d294a65 Added screen reader text to events. 2016-10-01 15:29:06 +03:00
Andrey Savchenko ec5adbf47a Recompiled assets. 2016-10-01 14:59:11 +03:00
Andrey Savchenko b26ea48216 Updated dependencies. 2016-10-01 14:58:55 +03:00
Andrey Savchenko 711371c226 Removed release Robo task. 2016-10-01 14:52:48 +03:00
Andrey Savchenko 72ff60fe6e Updated change log to keepachangelog format. 2016-10-01 14:51:22 +03:00
Andrey Savchenko 357753f84b Updated changelog and version for 1.3.2 2015-08-27 14:06:08 +03:00
Andrey Savchenko 9d1dddb462 Normalized slashing on adding files to release zip file. 2015-08-27 14:05:48 +03:00
Andrey Savchenko d88a566aee Fixed dynamic method call to prevent crash on PHP 7. 2015-08-27 14:05:19 +03:00
Andrey Savchenko b976b26454 Updated version in header 2015-08-15 21:06:35 +03:00
Andrey Savchenko a00b11f78a Updated changelog for 1.3.1 2015-08-12 00:15:24 +03:00
Andrey Savchenko 32f300af7f Added check to catch event stops without matching starts
Fixes #7
2015-08-12 00:14:33 +03:00
Andrey Savchenko a3572063d2 Updated changelog and version 2015-06-12 22:06:33 +03:00
Andrey Savchenko e8f8e9a4b6 Implemented release command in robo 2015-06-12 21:06:07 +03:00
Andrey Savchenko cf44efbe64 Added version getter to robo file 2015-06-12 21:05:50 +03:00
Andrey Savchenko 2289923666 Updated main file for code style 2015-06-12 21:05:24 +03:00
Andrey Savchenko b82cd35cf8 Updated gitignore 2015-06-12 20:58:52 +03:00
Andrey Savchenko 8e441c935f Added task to set plugin version 2015-06-11 17:23:31 +03:00
Andrey Savchenko 7dfea751f5 Made method calls more compact 2015-06-11 12:40:19 +03:00
Andrey Savchenko a3cc36b661 Removed commented out debug code 2015-06-11 12:40:07 +03:00
Andrey Savchenko 47caf94cfe Another end of file new line 2015-06-11 12:33:45 +03:00
Andrey Savchenko d8298b1700 Made comparisons strict 2015-06-11 12:27:28 +03:00
Andrey Savchenko 5072bbbaad Added new lines to end of files for code style 2015-06-11 12:26:27 +03:00
Andrey Savchenko b32d60dfce Updated Stopwatch dependency 2015-06-11 12:26:00 +03:00
Andrey Savchenko c593e1e925 Tightened condition on Hybrid events to prevent breakage with v3
Fixes #4
2015-06-11 11:56:02 +03:00
Andrey Savchenko 112c14fde3 Added events class for Yoast plugins 2015-04-06 10:19:57 +03:00
Andrey Savchenko df40e389ad Precompiled Mustache template 2015-04-06 09:46:09 +03:00
Andrey Savchenko fb7b2f025a Added Robo task for precompiling Mustache cache 2015-04-06 09:45:44 +03:00
Andrey Savchenko b87ce58f4a Implemented class for loading precompiled Mustache cache 2015-04-06 09:45:12 +03:00
Andrey Savchenko 424fb74b29 Updated dependencies 2015-04-06 09:44:18 +03:00
Andrey Savchenko 5ed687499f Recompiled assets after dependencies update 2015-03-28 23:36:08 +02:00
Andrey Savchenko 1db8318edb Updated dependencies 2015-03-28 23:35:05 +02:00
Andrey Savchenko edb804d35f Update README.md
Added link to releases section for archive download.
2015-02-06 23:20:32 +01:00
Andrey Savchenko ce265e6dd2 Updated array keys for coding style. 2015-01-03 21:24:58 +02:00
Andrey Savchenko f3438de84b Implemented minified assets in queue. 2015-01-03 21:06:32 +02:00
Andrey Savchenko d0d70fddaf Recompiled assets. 2015-01-03 21:06:11 +02:00
Andrey Savchenko 48424c2b4c Updated RoboFile for less sourcemap and minified assets. 2015-01-03 21:05:40 +02:00
Andrey Savchenko b3be169798 Updated dependencies. 2015-01-03 20:49:14 +02:00
Andrey Savchenko 5a33c9329b Split plugins load into file load and following hook. 2014-11-07 20:55:37 +02:00
Andrey Savchenko 6fda82d443 Recompiled assets after Bootstrap update. 2014-10-30 17:34:15 +02:00
Andrey Savchenko c912f263a2 Updated Bootstrap dependency to 3.3.0 2014-10-30 17:32:56 +02:00
Andrey Savchenko 6c75879465 Adjusted command name in RoboFile to make what, not what from. 2014-10-24 15:42:22 +03:00
Andrey Savchenko db87114e3f Elaborated on Composer code use in license section. 2014-10-24 15:10:12 +03:00
Andrey Savchenko 6c7b6d6195 Added links to themes and docs. 2014-10-24 15:09:47 +03:00
Andrey Savchenko 40fd25490b Moved screenshot up for eye candy. 2014-10-24 15:09:22 +03:00
Andrey Savchenko f2f3c4f474 Updated dependencies. 2014-10-23 22:38:26 +03:00
Andrey Savchenko 59bc49bd56 Updated readme and moved changelog to separate file. 2014-10-23 22:15:24 +03:00
Andrey Savchenko 234ed808aa Recompiled JS and updated for new script name. 2014-10-23 22:11:53 +03:00
Andrey Savchenko b5161c2955 Updated compilation and watch commands in RoboFile. 2014-10-23 22:11:06 +03:00
Andrey Savchenko 4cdf206de9 Moved JS from inline PHP to own source file. 2014-10-23 22:09:48 +03:00
25 changed files with 932 additions and 316 deletions

No files matched your search

+2 -1
View File
@@ -1 +1,2 @@
vendor /vendor
/release
+81
View File
@@ -0,0 +1,81 @@
# Change Log
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## Unreleased
## 1.4.1 - 2016-12-01
### Fixed
- errors and crash on WP 4.7 beta (not fully functional yet)
## 1.4 - 2016-10-01
### Added
- added screen reader text to events
- colorized writing SQL queries to warning color
### Changed
- updated change log format to Keep a Changelog
- updated dependencies (Stopwatch 2.8.11, Mustache 2.11.1, Bootstrap 3.3.7)
- updated assets
### Removed
- removed release Robo task
## 1.3.2 - 2015-08-27
### Fixed
- fixed dynamic method call crash on PHP 7
- fixed issue with slashes in generated release archives
## 1.3.1 - 2015-08-12
### Fixed
- fixed crash on event stop without matching start
## 1.3 - 2015-06-12
### Added
- implemented minified assets
- implemented pre-cached template
- implemented release build command
- added WP SEO event
### Changed
- split plugins_loaded hook into separate event
### Fixed
- fixed crash with upcoming Hybrid Core v3
## 1.2.1 - 2014-07-12
### Fixed
- disabled tooltip animation to fix JS errors and UI disappearing from under cursor
## 1.2 - 2014-05-18
### Added
- implemented (ballpark) toolbar event
### Changed
- merged RP with additional core events in admin
### Fixed
- fixed issue with event offsets in timelines
## 1.1 - 2013-12-11
### Added
- added SQL timeline
- added HTTP timeline
### Changed
- switched tooltips implementation to Bootstrap script
## 1.0 - 2013-04-22
### Added
- Initial public release
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2013 Andrey Savchenko
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+46 -68
View File
@@ -1,68 +1,46 @@
# Laps — light WP profiler # Laps — light WordPress profiler
Laps is light WordPress profiler (in a plugin), which aims to be: ![Laps screenshot](http://i.imgur.com/zFokmkU.png)
- always on and zero click (just hover on toolbar entry) away Laps is light WordPress profiler (in a plugin), which aims to be:
- quick indicator of what hogs page in general or right now
- always on and zero click (just hover on toolbar entry) away
It is no match or replacement for *real* profiler, but is friendly and cute. - quick indicator of what hogs page in general or right now
Out of the box Laps supports common stage of WordPress page life cycle: It is no match or replacement for *real* profiler, but is friendly and cute.
- plugins load Out of the box Laps supports common stage of WordPress page life cycle:
- themes load
- core init - plugins load
- main loop - themes load
- core init
And some of third party hooks conventions for themes using: - main loop
- Theme Hook Alliance And some of third party hooks conventions for themes using:
- Hybrid
- Genesis - [Theme Hook Alliance](http://zamoose.github.io/themehookalliance/)
- Thematic - [Hybrid](http://themehybrid.com/)
- [Genesis](http://my.studiopress.com/themes/genesis/)
There are also additional optional timelines, displaying: - [Thematic](http://thematictheme.com/)
- SQL queries (with `SAVEQUERIES` constant enabled) There are also additional optional timelines, displaying:
- HTTP requests performed
- SQL queries (with [`SAVEQUERIES` constant](http://codex.wordpress.org/Editing_wp-config.php#Save_queries_for_analysis) enabled)
# Screenshot - HTTP requests performed
![Laps screenshot](http://i.imgur.com/zFokmkU.png) ## Installation
# Installation Download plugin archive from [releases section](https://github.com/Rarst/laps/releases).
Laps is a Composer package and can be installed in plugin directory via: Or install in plugin directory via [Composer](https://getcomposer.org/):
composer create-project rarst/laps --no-dev composer create-project rarst/laps --no-dev
# Changelog ## License Info
## 1.2.1 Laps own code is licensed under MIT and it makes use of code from:
- disabled tooltip animation to fix JS errors and UI disappearing from under cursor - Composer Installers (MIT)
- Symfony Stopwatch (MIT)
## 1.2 - Mustache.php (MIT)
- Twitter Bootstrap (MIT)
- merged RP with additional core events in admin
- implemented (ballpark) toolbar event
- fixed issue with event offsets in timelines
## 1.1
- added SQL timeline
- added HTTP timeline
- switched tooltips implementation to Bootstrap script
## 1.0
- Initial public release
# License Info
Laps own code is licensed under MIT and it makes use of code from:
- Composer (MIT)
- Symfony Stopwatch (MIT)
- Mustache.php (MIT)
- Twitter Bootstrap (MIT)
+65 -24
View File
@@ -1,5 +1,7 @@
<?php <?php
require __DIR__ . '/vendor/autoload.php';
/** /**
* This is project's console commands configuration for Robo task runner. * This is project's console commands configuration for Robo task runner.
* *
@@ -12,40 +14,79 @@ class RoboFile extends \Robo\Tasks {
*/ */
public function watch() { public function watch() {
$less_callback = function () {
$this->less();
};
$this->taskWatch() $this->taskWatch()
->monitor( 'css/variables.less', $less_callback ) ->monitor( [ 'css/variables.less', 'css/laps.less' ], function () {
->monitor( 'css/laps.less', $less_callback ) $this->makeCss();
->run(); } )
->monitor( 'js/source.js', function () {
$this->makeJs();
} )
->run();
} }
/** /**
* Compiles stylesheet from less into css. * Compiles all assets.
*/ */
public function less() { public function makeAll() {
$this->taskExec( 'lessc css/laps.less css/laps.css' )->run(); $this->makeCss();
$this->makeJs();
$this->makeMustache();
} }
/** /**
* Copies tooltip.js from Bootstrap sources and edits plugin name. * Compiles plugin's css file from less.
*/ */
public function tooltip() { public function makeCss() {
$replacements = array( $this->taskExec( 'lessc css/laps.less css/laps.css --source-map=css/laps.css.map' )->run();
'+function ($) {' => '// modified to use lapstooltip as plugin name' . "\n\n" . '+function ($) {',
'this.init(\'tooltip\'' => 'this.init(\'lapstooltip\'', $this->taskMinify( 'css/laps.css' )
'bs.tooltip' => 'bs.lapstooltip', ->run();
'$.fn.tooltip' => '$.fn.lapstooltip', }
/**
* Creates plugin's script file.
*/
public function makeJs() {
$this->taskConcat( [
'vendor/twbs/bootstrap/js/tooltip.js',
'js/source.js',
] )
->to( 'js/laps.js' )
->run();
$this->taskMinify( 'js/laps.js' )
->run();
}
/**
* Compiles plugin's mustache template
*/
public function makeMustache() {
$dir = __DIR__ . '/views/cache';
$this->_cleanDir( $dir );
$mustache = new \Mustache_Engine(
array(
'loader' => new \Mustache_Loader_FilesystemLoader( __DIR__ . '/views' ),
'cache' => $dir,
)
); );
$mustache->loadTemplate( 'laps' );
$source = strtr( file_get_contents( 'vendor/twbs/bootstrap/js/tooltip.js' ), $replacements );
$this->taskWriteToFile( 'js/tooltip.js' )
->text( $source )
->run();
} }
}
/**
* Sets the plugin version in header.
*
* @param string $version Version string.
*/
public function versionSet( $version ) {
$this->taskReplaceInFile( 'laps.php' )
->regex( '|^Version:.*$|m' )
->to( 'Version: ' . $version )
->run();
}
}
Generated
+63 -41
View File
@@ -1,25 +1,29 @@
{ {
"_readme": [ "_readme": [
"This file locks the dependencies of your project to a known state", "This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "7495421e8df337988c9906e05aab637b", "hash": "7495421e8df337988c9906e05aab637b",
"content-hash": "3a8ac6bb545eee9eb5d1ce8b87136995",
"packages": [ "packages": [
{ {
"name": "composer/installers", "name": "composer/installers",
"version": "v1.0.15", "version": "v1.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/composer/installers.git", "url": "https://github.com/composer/installers.git",
"reference": "8e6a72a78f6cfd537fde3350720dfdc9ae3c5621" "reference": "d78064c68299743e0161004f2de3a0204e33b804"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/composer/installers/zipball/8e6a72a78f6cfd537fde3350720dfdc9ae3c5621", "url": "https://api.github.com/repos/composer/installers/zipball/d78064c68299743e0161004f2de3a0204e33b804",
"reference": "8e6a72a78f6cfd537fde3350720dfdc9ae3c5621", "reference": "d78064c68299743e0161004f2de3a0204e33b804",
"shasum": "" "shasum": ""
}, },
"require": {
"composer-plugin-api": "^1.0"
},
"replace": { "replace": {
"roundcube/plugin-installer": "*", "roundcube/plugin-installer": "*",
"shama/baton": "*" "shama/baton": "*"
@@ -28,16 +32,16 @@
"composer/composer": "1.0.*@dev", "composer/composer": "1.0.*@dev",
"phpunit/phpunit": "4.1.*" "phpunit/phpunit": "4.1.*"
}, },
"type": "composer-installer", "type": "composer-plugin",
"extra": { "extra": {
"class": "Composer\\Installers\\Installer", "class": "Composer\\Installers\\Plugin",
"branch-alias": { "branch-alias": {
"dev-master": "1.0-dev" "dev-master": "1.0-dev"
} }
}, },
"autoload": { "autoload": {
"psr-0": { "psr-4": {
"Composer\\Installers\\": "src/" "Composer\\Installers\\": "src/Composer/Installers"
} }
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
@@ -48,29 +52,41 @@
{ {
"name": "Kyle Robinson Young", "name": "Kyle Robinson Young",
"email": "kyle@dontkry.com", "email": "kyle@dontkry.com",
"homepage": "https://github.com/shama", "homepage": "https://github.com/shama"
"role": "Developer"
} }
], ],
"description": "A multi-framework Composer library installer", "description": "A multi-framework Composer library installer",
"homepage": "http://composer.github.com/installers/", "homepage": "https://composer.github.io/installers/",
"keywords": [ "keywords": [
"Craft", "Craft",
"Dolibarr", "Dolibarr",
"Hurad", "Hurad",
"ImageCMS",
"MODX Evo", "MODX Evo",
"Mautic",
"OXID", "OXID",
"Plentymarkets",
"RadPHP",
"SMF",
"Thelia",
"WolfCMS", "WolfCMS",
"agl", "agl",
"aimeos",
"annotatecms", "annotatecms",
"attogram",
"bitrix", "bitrix",
"cakephp", "cakephp",
"chef",
"cockpit",
"codeigniter", "codeigniter",
"concrete5", "concrete5",
"croogo", "croogo",
"dokuwiki",
"drupal", "drupal",
"elgg", "elgg",
"expressionengine",
"fuelphp", "fuelphp",
"grav",
"installer", "installer",
"joomla", "joomla",
"kohana", "kohana",
@@ -84,36 +100,40 @@
"phpbb", "phpbb",
"piwik", "piwik",
"ppi", "ppi",
"puppet",
"reindex",
"roundcube", "roundcube",
"shopware", "shopware",
"silverstripe", "silverstripe",
"symfony", "symfony",
"typo3", "typo3",
"wordpress", "wordpress",
"yawik",
"zend", "zend",
"zikula" "zikula"
], ],
"time": "2014-06-23 16:25:28" "time": "2016-08-13 20:53:52"
}, },
{ {
"name": "mustache/mustache", "name": "mustache/mustache",
"version": "v2.6.1", "version": "v2.11.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/bobthecow/mustache.php.git", "url": "https://github.com/bobthecow/mustache.php.git",
"reference": "1430ca884912eaba2b3830856b45685733b16789" "reference": "a3f6d55996dd28b58f3a909d474189a3c1aa693f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/1430ca884912eaba2b3830856b45685733b16789", "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/a3f6d55996dd28b58f3a909d474189a3c1aa693f",
"reference": "1430ca884912eaba2b3830856b45685733b16789", "reference": "a3f6d55996dd28b58f3a909d474189a3c1aa693f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.2.4" "php": ">=5.2.4"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "*" "friendsofphp/php-cs-fixer": "~1.11",
"phpunit/phpunit": "~3.7|~4.0|~5.0"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@@ -138,36 +158,38 @@
"mustache", "mustache",
"templating" "templating"
], ],
"time": "2014-06-20 19:34:49" "time": "2016-07-31 06:18:27"
}, },
{ {
"name": "symfony/stopwatch", "name": "symfony/stopwatch",
"version": "v2.5.0", "version": "v2.8.11",
"target-dir": "Symfony/Component/Stopwatch",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Stopwatch.git", "url": "https://github.com/symfony/stopwatch.git",
"reference": "724d73604ebe6c1c9bdf36533b556123bd9075a1" "reference": "35bae476693150728b0eb51647faac82faf9aaca"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/724d73604ebe6c1c9bdf36533b556123bd9075a1", "url": "https://api.github.com/repos/symfony/stopwatch/zipball/35bae476693150728b0eb51647faac82faf9aaca",
"reference": "724d73604ebe6c1c9bdf36533b556123bd9075a1", "reference": "35bae476693150728b0eb51647faac82faf9aaca",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.3" "php": ">=5.3.9"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.5-dev" "dev-master": "2.8-dev"
} }
}, },
"autoload": { "autoload": {
"psr-0": { "psr-4": {
"Symfony\\Component\\Stopwatch\\": "" "Symfony\\Component\\Stopwatch\\": ""
} },
"exclude-from-classmap": [
"/Tests/"
]
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
@@ -176,33 +198,31 @@
"authors": [ "authors": [
{ {
"name": "Fabien Potencier", "name": "Fabien Potencier",
"email": "fabien@symfony.com", "email": "fabien@symfony.com"
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
}, },
{ {
"name": "Symfony Community", "name": "Symfony Community",
"homepage": "http://symfony.com/contributors" "homepage": "https://symfony.com/contributors"
} }
], ],
"description": "Symfony Stopwatch Component", "description": "Symfony Stopwatch Component",
"homepage": "http://symfony.com", "homepage": "https://symfony.com",
"time": "2014-04-18 20:40:13" "time": "2016-06-29 05:29:29"
} }
], ],
"packages-dev": [ "packages-dev": [
{ {
"name": "twbs/bootstrap", "name": "twbs/bootstrap",
"version": "v3.2.0", "version": "v3.3.7",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/twbs/bootstrap.git", "url": "https://github.com/twbs/bootstrap.git",
"reference": "c068162161154a4b85110ea1e7dd3d7897ce2b72" "reference": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/twbs/bootstrap/zipball/c068162161154a4b85110ea1e7dd3d7897ce2b72", "url": "https://api.github.com/repos/twbs/bootstrap/zipball/0b9c4a4007c44201dce9a6cc1a38407005c26c86",
"reference": "c068162161154a4b85110ea1e7dd3d7897ce2b72", "reference": "0b9c4a4007c44201dce9a6cc1a38407005c26c86",
"shasum": "" "shasum": ""
}, },
"replace": { "replace": {
@@ -211,7 +231,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "3.2.x-dev" "dev-master": "3.3.x-dev"
} }
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
@@ -240,12 +260,14 @@
"responsive", "responsive",
"web" "web"
], ],
"time": "2014-06-26 16:36:48" "time": "2016-07-25 15:51:55"
} }
], ],
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": [], "stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [], "platform": [],
"platform-dev": [] "platform-dev": []
} }
+40 -21
View File
@@ -33,7 +33,7 @@
height: 100%; height: 100%;
font-size: 12px; font-size: 12px;
line-height: 20px; line-height: 20px;
color: #ffffff; color: #fff;
text-align: center; text-align: center;
background-color: #5bc0de; background-color: #5bc0de;
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
@@ -45,17 +45,6 @@
border-left: 1px solid #f5f5f5; border-left: 1px solid #f5f5f5;
min-width: 2px; min-width: 2px;
} }
#wpadminbar .laps-timeline .event[aria-valuenow="1"],
#wpadminbar .laps-timeline .event[aria-valuenow="2"] {
min-width: 30px;
}
#wpadminbar .laps-timeline .event[aria-valuenow="0"] {
color: #777777;
min-width: 30px;
background-color: transparent;
background-image: none;
box-shadow: none;
}
#wpadminbar .laps-timeline .event-theme { #wpadminbar .laps-timeline .event-theme {
background-color: #5cb85c; background-color: #5cb85c;
} }
@@ -65,19 +54,45 @@
#wpadminbar .laps-timeline .event-core { #wpadminbar .laps-timeline .event-core {
background-color: #f0ad4e; background-color: #f0ad4e;
} }
#wpadminbar .laps-timeline .event-query { #wpadminbar .laps-timeline .event-query-read {
background-color: #5bc0de; background-color: #5bc0de;
} }
#wpadminbar .laps-timeline .event-query-write {
background-color: #d9534f;
}
#wpadminbar .laps-timeline .event-http { #wpadminbar .laps-timeline .event-http {
background-color: #d9534f; background-color: #d9534f;
} }
#wpadminbar .laps-timeline .sr-only {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
#wpadminbar .tooltip { #wpadminbar .tooltip {
position: absolute; position: absolute;
z-index: 100000; z-index: 100000;
display: block; display: block;
visibility: visible; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-style: normal;
font-weight: normal;
letter-spacing: normal;
line-break: auto;
line-height: 1.42857143;
text-align: left;
text-align: start;
text-decoration: none;
text-shadow: none;
text-transform: none;
white-space: normal;
word-break: normal;
word-spacing: normal;
word-wrap: normal;
font-size: 12px; font-size: 12px;
line-height: 1.4;
opacity: 0; opacity: 0;
filter: alpha(opacity=0); filter: alpha(opacity=0);
} }
@@ -104,9 +119,8 @@
#wpadminbar .tooltip-inner { #wpadminbar .tooltip-inner {
max-width: 300px; max-width: 300px;
padding: 3px 8px; padding: 3px 8px;
color: #cccccc; color: #ccc;
text-align: center; text-align: center;
text-decoration: none;
background-color: #464646; background-color: #464646;
border-radius: 4px; border-radius: 4px;
} }
@@ -126,13 +140,15 @@
} }
#wpadminbar .tooltip.top-left .tooltip-arrow { #wpadminbar .tooltip.top-left .tooltip-arrow {
bottom: 0; bottom: 0;
left: 5px; right: 5px;
margin-bottom: -5px;
border-width: 5px 5px 0; border-width: 5px 5px 0;
border-top-color: #464646; border-top-color: #464646;
} }
#wpadminbar .tooltip.top-right .tooltip-arrow { #wpadminbar .tooltip.top-right .tooltip-arrow {
bottom: 0; bottom: 0;
right: 5px; left: 5px;
margin-bottom: -5px;
border-width: 5px 5px 0; border-width: 5px 5px 0;
border-top-color: #464646; border-top-color: #464646;
} }
@@ -159,13 +175,15 @@
} }
#wpadminbar .tooltip.bottom-left .tooltip-arrow { #wpadminbar .tooltip.bottom-left .tooltip-arrow {
top: 0; top: 0;
left: 5px; right: 5px;
margin-top: -5px;
border-width: 0 5px 5px; border-width: 0 5px 5px;
border-bottom-color: #464646; border-bottom-color: #464646;
} }
#wpadminbar .tooltip.bottom-right .tooltip-arrow { #wpadminbar .tooltip.bottom-right .tooltip-arrow {
top: 0; top: 0;
right: 5px; left: 5px;
margin-top: -5px;
border-width: 0 5px 5px; border-width: 0 5px 5px;
border-bottom-color: #464646; border-bottom-color: #464646;
} }
@@ -177,3 +195,4 @@
line-height: 20px; line-height: 20px;
text-align: left; text-align: left;
} }
/*# sourceMappingURL=laps.css.map */
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["laps.less","C:/server/www/dev/wp-content/plugins/laps/vendor/twbs/bootstrap/less/progress-bars.less","C:/server/www/dev/wp-content/plugins/laps/vendor/twbs/bootstrap/less/mixins/vendor-prefixes.less","C:/server/www/dev/wp-content/plugins/laps/vendor/twbs/bootstrap/less/scaffolding.less","C:/server/www/dev/wp-content/plugins/laps/vendor/twbs/bootstrap/less/tooltip.less","C:/server/www/dev/wp-content/plugins/laps/vendor/twbs/bootstrap/less/mixins/reset-text.less","C:/server/www/dev/wp-content/plugins/laps/vendor/twbs/bootstrap/less/variables.less","C:/server/www/dev/wp-content/plugins/laps/vendor/twbs/bootstrap/less/mixins/opacity.less"],"names":[],"mappings":"AAMA,WAEC,mBAEC;EACC,cAAA;EACA,UAAA;EACA,eAAA;EACA,QAAA;;AARH,WAEC,mBASC;EACC,UAAA;;AAZH,WAgBC;EAEC,eAAA;;AAEA,WAJD,0BAIE;EACA,6BAAA;;AArBH,WAgBC,0BAQC;EACC,aAAA;;AAzBH,WA6BC;ECTC,gBAAA;EACA,YAAA;EACA,mBAAA;EACA,yBAAA;EACA,kBAAA;ECsCA,sDAAA;EACQ,8CAAA;EFhCR,aAAA;EACA,kBAAA;;AAhCF,WA6BC,eAKC;ECJA,WAAA;EACA,SAAA;EACA,YAAA;EACA,eAAA;EACA,iBAAA;EACA,WAAA;EACA,kBAAA;EACA,yBAAA;ECyBA,sDAAA;EACQ,8CAAA;EAyHR,mCAAA;EACK,8BAAA;EACG,2BAAA;EFtJP,kBAAA;EACA,8BAAA;EACA,cAAA;;AAtCH,WA6BC,eAYC;EACC,yBAAA;;AA1CH,WA6BC,eAeC;EACC,yBAAA;;AA7CH,WA6BC,eAkBC;EACC,yBAAA;;AAhDH,WA6BC,eAqBC;EACC,yBAAA;;AAnDH,WA6BC,eAwBC;EACC,yBAAA;;AAtDH,WA6BC,eA2BC;EACC,yBAAA;;AAzDH,WA6BC,eA+BC;EG2DA,kBAAA;EACA,UAAA;EACA,WAAA;EACA,YAAA;EACA,UAAA;EACA,gBAAA;EACA,MAAM,gBAAN;EACA,SAAA;;AH9HF,WIAA;EACE,kBAAA;EACA,eAAA;EACA,cAAA;ECRA,aC2CwB,8CD3CxB;EAEA,kBAAA;EACA,mBAAA;EACA,sBAAA;EACA,gBAAA;EACA,uBAAA;EACA,gBAAA;EACA,iBAAA;EACA,qBAAA;EACA,iBAAA;EACA,oBAAA;EACA,mBAAA;EACA,kBAAA;EACA,oBAAA;EACA,iBAAA;EDHA,eAAA;EGVA,UAAA;EAGA,wBAAA;;AHWA,WAXF,SAWG;EGdD,YAAA;EAGA,yBAAA;;AHYA,WAZF,SAYG;EAAU,gBAAA;EAAmB,cAAA;;AAC9B,WAbF,SAaG;EAAU,gBAAA;EAAmB,cAAA;;AAC9B,WAdF,SAcG;EAAU,eAAA;EAAmB,cAAA;;AAC9B,WAfF,SAeG;EAAU,iBAAA;EAAmB,cAAA;;AJfhC,WImBA;EACE,gBAAA;EACA,gBAAA;EACA,WAAA;EACA,kBAAA;EACA,yBAAA;EACA,kBAAA;;AJzBF,WI6BA;EACE,kBAAA;EACA,QAAA;EACA,SAAA;EACA,yBAAA;EACA,mBAAA;;AAIA,WADF,SACG,IAAK;EACJ,SAAA;EACA,SAAA;EACA,iBAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,WARF,SAQG,SAAU;EACT,SAAA;EACA,UAAA;EACA,mBAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,WAfF,SAeG,UAAW;EACV,SAAA;EACA,SAAA;EACA,mBAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,WAtBF,SAsBG,MAAO;EACN,QAAA;EACA,OAAA;EACA,gBAAA;EACA,2BAAA;EACA,2BAAA;;AAEF,WA7BF,SA6BG,KAAM;EACL,QAAA;EACA,QAAA;EACA,gBAAA;EACA,2BAAA;EACA,0BAAA;;AAEF,WApCF,SAoCG,OAAQ;EACP,MAAA;EACA,SAAA;EACA,iBAAA;EACA,uBAAA;EACA,4BAAA;;AAEF,WA3CF,SA2CG,YAAa;EACZ,MAAA;EACA,UAAA;EACA,gBAAA;EACA,uBAAA;EACA,4BAAA;;AAEF,WAlDF,SAkDG,aAAc;EACb,MAAA;EACA,SAAA;EACA,gBAAA;EACA,uBAAA;EACA,4BAAA;;AJ5FJ,WAmEC,SAAQ;EOtEP,UAAA;EAGA,0BAAA;;APAF,WAuEC;EACC,iBAAA;EACA,gBAAA","file":"laps.css"}
+9 -1
View File
@@ -1,6 +1,7 @@
@import (reference) "../vendor/twbs/bootstrap/less/variables.less"; @import (reference) "../vendor/twbs/bootstrap/less/variables.less";
@import (reference) "../vendor/twbs/bootstrap/less/mixins.less"; @import (reference) "../vendor/twbs/bootstrap/less/mixins.less";
@import (reference) "../vendor/twbs/bootstrap/less/progress-bars.less"; @import (reference) "../vendor/twbs/bootstrap/less/progress-bars.less";
@import (reference) "../vendor/twbs/bootstrap/less/scaffolding.less";
@import "variables.less"; @import "variables.less";
#wpadminbar { #wpadminbar {
@@ -53,12 +54,19 @@
.event-core { .event-core {
background-color: @event-core-color; background-color: @event-core-color;
} }
.event-query { .event-query-read {
background-color: @event-info-color; background-color: @event-info-color;
} }
.event-query-write {
background-color: @event-warning-color;
}
.event-http { .event-http {
background-color: @event-warning-color; background-color: @event-warning-color;
} }
.sr-only {
.sr-only;
}
} }
@import "../vendor/twbs/bootstrap/less/tooltip.less"; @import "../vendor/twbs/bootstrap/less/tooltip.less";
+1
View File
@@ -0,0 +1 @@
#wpadminbar #wp-admin-bar-laps .ab-sub-wrapper{min-width:90%;width:90%;position:fixed;left:5%}#wpadminbar #wp-admin-bar-laps .ab-submenu{padding:0}#wpadminbar #wp-admin-bar-laps_output{padding:0 10px}#wpadminbar #wp-admin-bar-laps_output:hover{background-color:transparent}#wpadminbar #wp-admin-bar-laps_output .ab-empty-item{display:none}#wpadminbar .laps-timeline{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);margin:6px 0;position:relative}#wpadminbar .laps-timeline .event{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#5bc0de;-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;position:absolute;border-left:1px solid #f5f5f5;min-width:2px}#wpadminbar .laps-timeline .event-theme{background-color:#5cb85c}#wpadminbar .laps-timeline .event-plugin{background-color:#428bca}#wpadminbar .laps-timeline .event-core{background-color:#f0ad4e}#wpadminbar .laps-timeline .event-query-read{background-color:#5bc0de}#wpadminbar .laps-timeline .event-query-write{background-color:#d9534f}#wpadminbar .laps-timeline .event-http{background-color:#d9534f}#wpadminbar .laps-timeline .sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}#wpadminbar .tooltip{position:absolute;z-index:100000;display:block;font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)}#wpadminbar .tooltip.in{opacity:0.9;filter:alpha(opacity=90)}#wpadminbar .tooltip.top{margin-top:-3px;padding:5px 0}#wpadminbar .tooltip.right{margin-left:3px;padding:0 5px}#wpadminbar .tooltip.bottom{margin-top:3px;padding:5px 0}#wpadminbar .tooltip.left{margin-left:-3px;padding:0 5px}#wpadminbar .tooltip-inner{max-width:300px;padding:3px 8px;color:#ccc;text-align:center;background-color:#464646;border-radius:4px}#wpadminbar .tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}#wpadminbar .tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#464646}#wpadminbar .tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#464646}#wpadminbar .tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#464646}#wpadminbar .tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#464646}#wpadminbar .tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#464646}#wpadminbar .tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#464646}#wpadminbar .tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#464646}#wpadminbar .tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#464646}#wpadminbar .tooltip.in{opacity:1;filter:alpha(opacity=100)}#wpadminbar .tooltip-inner{line-height:20px;text-align:left}
+138 -64
View File
@@ -1,15 +1,13 @@
/* ======================================================================== /* ========================================================================
* Bootstrap: tooltip.js v3.2.0 * Bootstrap: tooltip.js v3.3.7
* http://getbootstrap.com/javascript/#tooltip * http://getbootstrap.com/javascript/#tooltip
* Inspired by the original jQuery.tipsy by Jason Frame * Inspired by the original jQuery.tipsy by Jason Frame
* ======================================================================== * ========================================================================
* Copyright 2011-2014 Twitter, Inc. * Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */ * ======================================================================== */
// modified to use lapstooltip as plugin name
+function ($) { +function ($) {
'use strict'; 'use strict';
@@ -17,17 +15,20 @@
// =============================== // ===============================
var Tooltip = function (element, options) { var Tooltip = function (element, options) {
this.type = this.type = null
this.options = this.options = null
this.enabled = this.enabled = null
this.timeout = this.timeout = null
this.hoverState = this.hoverState = null
this.$element = null this.$element = null
this.inState = null
this.init('lapstooltip', element, options) this.init('tooltip', element, options)
} }
Tooltip.VERSION = '3.2.0' Tooltip.VERSION = '3.3.7'
Tooltip.TRANSITION_DURATION = 150
Tooltip.DEFAULTS = { Tooltip.DEFAULTS = {
animation: true, animation: true,
@@ -50,7 +51,12 @@
this.type = type this.type = type
this.$element = $(element) this.$element = $(element)
this.options = this.getOptions(options) this.options = this.getOptions(options)
this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
this.inState = { click: false, hover: false, focus: false }
if (this.$element[0] instanceof document.constructor && !this.options.selector) {
throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
}
var triggers = this.options.trigger.split(' ') var triggers = this.options.trigger.split(' ')
@@ -110,6 +116,15 @@
$(obj.currentTarget).data('bs.' + this.type, self) $(obj.currentTarget).data('bs.' + this.type, self)
} }
if (obj instanceof $.Event) {
self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
}
if (self.tip().hasClass('in') || self.hoverState == 'in') {
self.hoverState = 'in'
return
}
clearTimeout(self.timeout) clearTimeout(self.timeout)
self.hoverState = 'in' self.hoverState = 'in'
@@ -121,6 +136,14 @@
}, self.options.delay.show) }, self.options.delay.show)
} }
Tooltip.prototype.isInStateTrue = function () {
for (var key in this.inState) {
if (this.inState[key]) return true
}
return false
}
Tooltip.prototype.leave = function (obj) { Tooltip.prototype.leave = function (obj) {
var self = obj instanceof this.constructor ? var self = obj instanceof this.constructor ?
obj : $(obj.currentTarget).data('bs.' + this.type) obj : $(obj.currentTarget).data('bs.' + this.type)
@@ -130,6 +153,12 @@
$(obj.currentTarget).data('bs.' + this.type, self) $(obj.currentTarget).data('bs.' + this.type, self)
} }
if (obj instanceof $.Event) {
self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
}
if (self.isInStateTrue()) return
clearTimeout(self.timeout) clearTimeout(self.timeout)
self.hoverState = 'out' self.hoverState = 'out'
@@ -147,7 +176,7 @@
if (this.hasContent() && this.enabled) { if (this.hasContent() && this.enabled) {
this.$element.trigger(e) this.$element.trigger(e)
var inDom = $.contains(document.documentElement, this.$element[0]) var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
if (e.isDefaultPrevented() || !inDom) return if (e.isDefaultPrevented() || !inDom) return
var that = this var that = this
@@ -176,6 +205,7 @@
.data('bs.' + this.type, this) .data('bs.' + this.type, this)
this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
this.$element.trigger('inserted.bs.' + this.type)
var pos = this.getPosition() var pos = this.getPosition()
var actualWidth = $tip[0].offsetWidth var actualWidth = $tip[0].offsetWidth
@@ -183,13 +213,12 @@
if (autoPlace) { if (autoPlace) {
var orgPlacement = placement var orgPlacement = placement
var $parent = this.$element.parent() var viewportDim = this.getPosition(this.$viewport)
var parentDim = this.getPosition($parent)
placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' : placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' : placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' : placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' : placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
placement placement
$tip $tip
@@ -202,14 +231,17 @@
this.applyPlacement(calculatedOffset, placement) this.applyPlacement(calculatedOffset, placement)
var complete = function () { var complete = function () {
var prevHoverState = that.hoverState
that.$element.trigger('shown.bs.' + that.type) that.$element.trigger('shown.bs.' + that.type)
that.hoverState = null that.hoverState = null
if (prevHoverState == 'out') that.leave(that)
} }
$.support.transition && this.$tip.hasClass('fade') ? $.support.transition && this.$tip.hasClass('fade') ?
$tip $tip
.one('bsTransitionEnd', complete) .one('bsTransitionEnd', complete)
.emulateTransitionEnd(150) : .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
complete() complete()
} }
} }
@@ -227,8 +259,8 @@
if (isNaN(marginTop)) marginTop = 0 if (isNaN(marginTop)) marginTop = 0
if (isNaN(marginLeft)) marginLeft = 0 if (isNaN(marginLeft)) marginLeft = 0
offset.top = offset.top + marginTop offset.top += marginTop
offset.left = offset.left + marginLeft offset.left += marginLeft
// $.fn.offset doesn't round pixel values // $.fn.offset doesn't round pixel values
// so we use setOffset directly with our own function B-0 // so we use setOffset directly with our own function B-0
@@ -256,16 +288,18 @@
if (delta.left) offset.left += delta.left if (delta.left) offset.left += delta.left
else offset.top += delta.top else offset.top += delta.top
var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight var isVertical = /top|bottom/.test(placement)
var arrowPosition = delta.left ? 'left' : 'top' var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight' var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
$tip.offset(offset) $tip.offset(offset)
this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition) this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
} }
Tooltip.prototype.replaceArrow = function (delta, dimension, position) { Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '') this.arrow()
.css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
.css(isVertical ? 'top' : 'left', '')
} }
Tooltip.prototype.setContent = function () { Tooltip.prototype.setContent = function () {
@@ -276,16 +310,19 @@
$tip.removeClass('fade in top bottom left right') $tip.removeClass('fade in top bottom left right')
} }
Tooltip.prototype.hide = function () { Tooltip.prototype.hide = function (callback) {
var that = this var that = this
var $tip = this.tip() var $tip = $(this.$tip)
var e = $.Event('hide.bs.' + this.type) var e = $.Event('hide.bs.' + this.type)
this.$element.removeAttr('aria-describedby')
function complete() { function complete() {
if (that.hoverState != 'in') $tip.detach() if (that.hoverState != 'in') $tip.detach()
that.$element.trigger('hidden.bs.' + that.type) if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
that.$element
.removeAttr('aria-describedby')
.trigger('hidden.bs.' + that.type)
}
callback && callback()
} }
this.$element.trigger(e) this.$element.trigger(e)
@@ -294,10 +331,10 @@
$tip.removeClass('in') $tip.removeClass('in')
$.support.transition && this.$tip.hasClass('fade') ? $.support.transition && $tip.hasClass('fade') ?
$tip $tip
.one('bsTransitionEnd', complete) .one('bsTransitionEnd', complete)
.emulateTransitionEnd(150) : .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
complete() complete()
this.hoverState = null this.hoverState = null
@@ -307,7 +344,7 @@
Tooltip.prototype.fixTitle = function () { Tooltip.prototype.fixTitle = function () {
var $e = this.$element var $e = this.$element
if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') { if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
$e.attr('data-original-title', $e.attr('title') || '').attr('title', '') $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
} }
} }
@@ -318,20 +355,30 @@
Tooltip.prototype.getPosition = function ($element) { Tooltip.prototype.getPosition = function ($element) {
$element = $element || this.$element $element = $element || this.$element
var el = $element[0] var el = $element[0]
var isBody = el.tagName == 'BODY' var isBody = el.tagName == 'BODY'
return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(), var elRect = el.getBoundingClientRect()
width: isBody ? $(window).width() : $element.outerWidth(), if (elRect.width == null) {
height: isBody ? $(window).height() : $element.outerHeight() // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
}, isBody ? { top: 0, left: 0 } : $element.offset()) elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
}
var isSvg = window.SVGElement && el instanceof window.SVGElement
// Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
// See https://github.com/twbs/bootstrap/issues/20280
var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
return $.extend({}, elRect, scroll, outerDims, elOffset)
} }
Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
/* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
} }
@@ -355,7 +402,7 @@
var rightEdgeOffset = pos.left + viewportPadding + actualWidth var rightEdgeOffset = pos.left + viewportPadding + actualWidth
if (leftEdgeOffset < viewportDimensions.left) { // left overflow if (leftEdgeOffset < viewportDimensions.left) { // left overflow
delta.left = viewportDimensions.left - leftEdgeOffset delta.left = viewportDimensions.left - leftEdgeOffset
} else if (rightEdgeOffset > viewportDimensions.width) { // right overflow } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
} }
} }
@@ -381,21 +428,19 @@
} }
Tooltip.prototype.tip = function () { Tooltip.prototype.tip = function () {
return (this.$tip = this.$tip || $(this.options.template)) if (!this.$tip) {
this.$tip = $(this.options.template)
if (this.$tip.length != 1) {
throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
}
}
return this.$tip
} }
Tooltip.prototype.arrow = function () { Tooltip.prototype.arrow = function () {
return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
} }
Tooltip.prototype.validate = function () {
if (!this.$element[0].parentNode) {
this.hide()
this.$element = null
this.options = null
}
}
Tooltip.prototype.enable = function () { Tooltip.prototype.enable = function () {
this.enabled = true this.enabled = true
} }
@@ -418,12 +463,28 @@
} }
} }
self.tip().hasClass('in') ? self.leave(self) : self.enter(self) if (e) {
self.inState.click = !self.inState.click
if (self.isInStateTrue()) self.enter(self)
else self.leave(self)
} else {
self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
}
} }
Tooltip.prototype.destroy = function () { Tooltip.prototype.destroy = function () {
var that = this
clearTimeout(this.timeout) clearTimeout(this.timeout)
this.hide().$element.off('.' + this.type).removeData('bs.' + this.type) this.hide(function () {
that.$element.off('.' + that.type).removeData('bs.' + that.type)
if (that.$tip) {
that.$tip.detach()
}
that.$tip = null
that.$arrow = null
that.$viewport = null
that.$element = null
})
} }
@@ -433,27 +494,40 @@
function Plugin(option) { function Plugin(option) {
return this.each(function () { return this.each(function () {
var $this = $(this) var $this = $(this)
var data = $this.data('bs.lapstooltip') var data = $this.data('bs.tooltip')
var options = typeof option == 'object' && option var options = typeof option == 'object' && option
if (!data && option == 'destroy') return if (!data && /destroy|hide/.test(option)) return
if (!data) $this.data('bs.lapstooltip', (data = new Tooltip(this, options))) if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
if (typeof option == 'string') data[option]() if (typeof option == 'string') data[option]()
}) })
} }
var old = $.fn.lapstooltip var old = $.fn.tooltip
$.fn.lapstooltip = Plugin $.fn.tooltip = Plugin
$.fn.lapstooltip.Constructor = Tooltip $.fn.tooltip.Constructor = Tooltip
// TOOLTIP NO CONFLICT // TOOLTIP NO CONFLICT
// =================== // ===================
$.fn.lapstooltip.noConflict = function () { $.fn.tooltip.noConflict = function () {
$.fn.lapstooltip = old $.fn.tooltip = old
return this return this
} }
}(jQuery); }(jQuery);
jQuery.fn.lapstooltip = jQuery.fn.tooltip.noConflict();
jQuery(document).ready(function () {
jQuery(".laps-timeline .event").lapstooltip({
container: '#wpadminbar',
placement: 'bottom',
html : true,
animation: false
});
});
+6
View File
@@ -0,0 +1,6 @@
+function(t){'use strict';var e=function(t,e){this.type=null;this.options=null;this.enabled=null;this.timeout=null;this.hoverState=null;this.$element=null;this.inState=null;this.init('tooltip',t,e)};e.VERSION='3.3.7';e.TRANSITION_DURATION=150;e.DEFAULTS={animation:!0,placement:'top',selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:'hover focus',title:'',delay:0,html:!1,container:!1,viewport:{selector:'body',padding:0}};e.prototype.init=function(e,i,o){this.enabled=!0;this.type=e;this.$element=t(i);this.options=this.getOptions(o);this.$viewport=this.options.viewport&&t(t.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):(this.options.viewport.selector||this.options.viewport));this.inState={click:!1,hover:!1,focus:!1};if(this.$element[0]instanceof document.constructor&&!this.options.selector){throw new Error('`selector` option must be specified when initializing '+this.type+' on the window.document object!')};var r=this.options.trigger.split(' ');for(var s=r.length;s--;){var n=r[s];if(n=='click'){this.$element.on('click.'+this.type,this.options.selector,t.proxy(this.toggle,this))}
else if(n!='manual'){var l=n=='hover'?'mouseenter':'focusin',a=n=='hover'?'mouseleave':'focusout';this.$element.on(l+'.'+this.type,this.options.selector,t.proxy(this.enter,this));this.$element.on(a+'.'+this.type,this.options.selector,t.proxy(this.leave,this))}};this.options.selector?(this._options=t.extend({},this.options,{trigger:'manual',selector:''})):this.fixTitle()};e.prototype.getDefaults=function(){return e.DEFAULTS};e.prototype.getOptions=function(e){e=t.extend({},this.getDefaults(),this.$element.data(),e);if(e.delay&&typeof e.delay=='number'){e.delay={show:e.delay,hide:e.delay}};return e};e.prototype.getDelegateOptions=function(){var e={};var i=this.getDefaults();this._options&&t.each(this._options,function(t,o){if(i[t]!=o)e[t]=o});return e};e.prototype.enter=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data('bs.'+this.type);if(!i){i=new this.constructor(e.currentTarget,this.getDelegateOptions());t(e.currentTarget).data('bs.'+this.type,i)};if(e instanceof t.Event){i.inState[e.type=='focusin'?'focus':'hover']=!0};if(i.tip().hasClass('in')||i.hoverState=='in'){i.hoverState='in';return};clearTimeout(i.timeout);i.hoverState='in';if(!i.options.delay||!i.options.delay.show)return i.show();i.timeout=setTimeout(function(){if(i.hoverState=='in')i.show()},i.options.delay.show)};e.prototype.isInStateTrue=function(){for(var t in this.inState){if(this.inState[t])return!0};return!1};e.prototype.leave=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data('bs.'+this.type);if(!i){i=new this.constructor(e.currentTarget,this.getDelegateOptions());t(e.currentTarget).data('bs.'+this.type,i)};if(e instanceof t.Event){i.inState[e.type=='focusout'?'focus':'hover']=!1};if(i.isInStateTrue())return;clearTimeout(i.timeout);i.hoverState='out';if(!i.options.delay||!i.options.delay.hide)return i.hide();i.timeout=setTimeout(function(){if(i.hoverState=='out')i.hide()},i.options.delay.hide)};e.prototype.show=function(){var c=t.Event('show.bs.'+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(c);var v=t.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(c.isDefaultPrevented()||!v)return;var n=this,o=this.tip(),u=this.getUID(this.type);this.setContent();o.attr('id',u);this.$element.attr('aria-describedby',u);if(this.options.animation)o.addClass('fade');var i=typeof this.options.placement=='function'?this.options.placement.call(this,o[0],this.$element[0]):this.options.placement,h=/\s?auto?\s?/i,f=h.test(i);if(f)i=i.replace(h,'')||'top';o.detach().css({top:0,left:0,display:'block'}).addClass(i).data('bs.'+this.type,this);this.options.container?o.appendTo(this.options.container):o.insertAfter(this.$element);this.$element.trigger('inserted.bs.'+this.type);var s=this.getPosition(),l=o[0].offsetWidth,a=o[0].offsetHeight;if(f){var m=i,r=this.getPosition(this.$viewport);i=i=='bottom'&&s.bottom+a>r.bottom?'top':i=='top'&&s.top-a<r.top?'bottom':i=='right'&&s.right+l>r.width?'left':i=='left'&&s.left-l<r.left?'right':i;o.removeClass(m).addClass(i)};var d=this.getCalculatedOffset(i,s,l,a);this.applyPlacement(d,i);var p=function(){var t=n.hoverState;n.$element.trigger('shown.bs.'+n.type);n.hoverState=null;if(t=='out')n.leave(n)};t.support.transition&&this.$tip.hasClass('fade')?o.one('bsTransitionEnd',p).emulateTransitionEnd(e.TRANSITION_DURATION):p()}};e.prototype.applyPlacement=function(e,o){var i=this.tip(),c=i[0].offsetWidth,l=i[0].offsetHeight,a=parseInt(i.css('margin-top'),10),p=parseInt(i.css('margin-left'),10);if(isNaN(a))a=0;if(isNaN(p))p=0;e.top+=a;e.left+=p;t.offset.setOffset(i[0],t.extend({using:function(t){i.css({top:Math.round(t.top),left:Math.round(t.left)})}},e),0);i.addClass('in');var h=i[0].offsetWidth,s=i[0].offsetHeight;if(o=='top'&&s!=l){e.top=e.top+l-s};var n=this.getViewportAdjustedDelta(o,e,h,s);if(n.left)e.left+=n.left;else e.top+=n.top;var r=/top|bottom/.test(o),f=r?n.left*2-c+h:n.top*2-l+s,u=r?'offsetWidth':'offsetHeight';i.offset(e);this.replaceArrow(f,i[0][u],r)};e.prototype.replaceArrow=function(t,e,i){this.arrow().css(i?'left':'top',50*(1-t/e)+'%').css(i?'top':'left','')};e.prototype.setContent=function(){var t=this.tip(),e=this.getTitle();t.find('.tooltip-inner')[this.options.html?'html':'text'](e);t.removeClass('fade in top bottom left right')};e.prototype.hide=function(i){var o=this,n=t(this.$tip),s=t.Event('hide.bs.'+this.type);function r(){if(o.hoverState!='in')n.detach();if(o.$element){o.$element.removeAttr('aria-describedby').trigger('hidden.bs.'+o.type)};i&&i()};this.$element.trigger(s);if(s.isDefaultPrevented())return;n.removeClass('in');t.support.transition&&n.hasClass('fade')?n.one('bsTransitionEnd',r).emulateTransitionEnd(e.TRANSITION_DURATION):r();this.hoverState=null;return this};e.prototype.fixTitle=function(){var t=this.$element;if(t.attr('title')||typeof t.attr('data-original-title')!='string'){t.attr('data-original-title',t.attr('title')||'').attr('title','')}};e.prototype.hasContent=function(){return this.getTLine truncated
else if(h>e.top+e.height){o.top=e.top+e.height-h}}
else{var l=i.left-s,a=i.left+s+n;if(l<e.left){o.left=e.left-l}
else if(a>e.right){o.left=e.left+e.width-a}};return o};e.prototype.getTitle=function(){var e,i=this.$element,t=this.options;e=i.attr('data-original-title')||(typeof t.title=='function'?t.title.call(i[0]):t.title);return e};e.prototype.getUID=function(t){do t+=~~(Math.random()*1000000);while(document.getElementById(t))return t};e.prototype.tip=function(){if(!this.$tip){this.$tip=t(this.options.template);if(this.$tip.length!=1){throw new Error(this.type+' `template` option must consist of exactly 1 top-level element!')}};return this.$tip};e.prototype.arrow=function(){return(this.$arrow=this.$arrow||this.tip().find('.tooltip-arrow'))};e.prototype.enable=function(){this.enabled=!0};e.prototype.disable=function(){this.enabled=!1};e.prototype.toggleEnabled=function(){this.enabled=!this.enabled};e.prototype.toggle=function(e){var i=this;if(e){i=t(e.currentTarget).data('bs.'+this.type);if(!i){i=new this.constructor(e.currentTarget,this.getDelegateOptions());t(e.currentTarget).data('bs.'+this.type,i)}};if(e){i.inState.click=!i.inState.click;if(i.isInStateTrue())i.enter(i);else i.leave(i)}
else{i.tip().hasClass('in')?i.leave(i):i.enter(i)}};e.prototype.destroy=function(){var t=this;clearTimeout(this.timeout);this.hide(function(){t.$element.off('.'+t.type).removeData('bs.'+t.type);if(t.$tip){t.$tip.detach()};t.$tip=null;t.$arrow=null;t.$viewport=null;t.$element=null})};function o(i){return this.each(function(){var n=t(this),o=n.data('bs.tooltip'),s=typeof i=='object'&&i;if(!o&&/destroy|hide/.test(i))return;if(!o)n.data('bs.tooltip',(o=new e(this,s)));if(typeof i=='string')o[i]()})};var i=t.fn.tooltip;t.fn.tooltip=o;t.fn.tooltip.Constructor=e;t.fn.tooltip.noConflict=function(){t.fn.tooltip=i;return this}}(jQuery);jQuery.fn.lapstooltip=jQuery.fn.tooltip.noConflict();jQuery(document).ready(function(){jQuery('.laps-timeline .event').lapstooltip({container:'#wpadminbar',placement:'bottom',html:!0,animation:!1})});
+11
View File
@@ -0,0 +1,11 @@
jQuery.fn.lapstooltip = jQuery.fn.tooltip.noConflict();
jQuery(document).ready(function () {
jQuery(".laps-timeline .event").lapstooltip({
container: '#wpadminbar',
placement: 'bottom',
html : true,
animation: false
});
});
+4 -21
View File
@@ -4,32 +4,15 @@ Plugin Name: Laps
Plugin URI: https://github.com/Rarst/laps Plugin URI: https://github.com/Rarst/laps
Description: Light WordPress profiler. Description: Light WordPress profiler.
Author: Andrey "Rarst" Savchenko Author: Andrey "Rarst" Savchenko
Version: Version: 1.4.1
Author URI: http://www.rarst.net/ Author URI: http://www.rarst.net/
Text Domain: laps Text Domain: laps
Domain Path: /lang Domain Path: /lang
License: MIT License: MIT
Copyright (c) 2013 Andrey "Rarst" Savchenko
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/ */
if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
require __DIR__ . '/vendor/autoload.php'; require __DIR__ . '/vendor/autoload.php';
}
Rarst\Laps\Laps::on_load(); Rarst\Laps\Laps::on_load();
+13 -2
View File
@@ -14,12 +14,23 @@ class Core_Events extends Laps_Events {
$stops = array(); $stops = array();
$stops['plugins_loaded'][20] = array( $stops['plugins_loaded'][ - 2 ] = array(
'action' => 'stop', 'action' => 'stop',
'event' => 'Plugins Load', 'event' => 'Plugins Load',
'category' => 'plugin', 'category' => 'plugin',
); );
$stops['plugins_loaded'][ - 1 ] = array(
'event' => 'Plugins Loaded Hook',
'category' => 'plugin',
);
$stops['plugins_loaded'][20] = array(
'action' => 'stop',
'event' => 'Plugins Loaded Hook',
'category' => 'plugin',
);
$stops['setup_theme'][0] = array( $stops['setup_theme'][0] = array(
'event' => 'Themes Load', 'event' => 'Themes Load',
'category' => 'theme', 'category' => 'theme',
@@ -92,4 +103,4 @@ class Core_Events extends Laps_Events {
return $stops; return $stops;
} }
} }
+2 -2
View File
@@ -34,7 +34,7 @@ abstract class Laps_Events {
/** /**
* Inherit with internal events compiling and return * Inherit with internal events compiling and return
* *
* @return array() * @return array
*/ */
abstract protected function get_events(); abstract protected function get_events();
} }
+1 -1
View File
@@ -59,4 +59,4 @@ class Genesis_Events extends Laps_Events {
return $events; return $events;
} }
} }
+2 -2
View File
@@ -14,7 +14,7 @@ class Hybrid_Events extends Laps_Events {
*/ */
protected function is_applicable() { protected function is_applicable() {
return defined( 'HYBRID_VERSION' ); return defined( 'HYBRID_VERSION' ) && function_exists( 'hybrid_get_prefix' );
} }
/** /**
@@ -56,4 +56,4 @@ class Hybrid_Events extends Laps_Events {
return $events; return $events;
} }
} }
+58 -63
View File
@@ -17,7 +17,7 @@ class Laps {
/** /**
* Start Stopwatch and timing plugin load immediately, then set up core events and needed hooks. * Start Stopwatch and timing plugin load immediately, then set up core events and needed hooks.
*/ */
static function on_load() { public static function on_load() {
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
return; return;
@@ -45,7 +45,7 @@ class Laps {
* *
* @param array $stops * @param array $stops
*/ */
static function add_events( $stops ) { public static function add_events( $stops ) {
self::$events = array_merge( self::$events, $stops ); self::$events = array_merge( self::$events, $stops );
@@ -65,14 +65,14 @@ class Laps {
* *
* @return array * @return array
*/ */
static function pre_update_option_active_plugins( $plugins ) { public static function pre_update_option_active_plugins( $plugins ) {
$plugin = plugin_basename( dirname( __DIR__ ) . '/laps.php' ); $plugin = plugin_basename( dirname( __DIR__ ) . '/laps.php' );
$key = array_search( $plugin, $plugins ); $key = array_search( $plugin, $plugins );
if ( false !== $key && $key > 0 ) { if ( false !== $key && $key > 0 ) {
unset( $plugins[$key] ); unset( $plugins[ $key ] );
array_unshift( $plugins, $plugin ); array_unshift( $plugins, $plugin );
$plugins = array_values( $plugins ); $plugins = array_values( $plugins );
} }
@@ -87,22 +87,30 @@ class Laps {
* *
* @return mixed * @return mixed
*/ */
static function tick( $input = null ) { public static function tick( $input = null ) {
global $wp_filter; global $wp_filter;
$filter = current_filter(); $filter = current_filter();
$priority = key( $wp_filter[$filter] ); $priority = key( $wp_filter[ $filter ] );
if ( 'callbacks' === $priority ) { // Fails on WP 4.7, see https://core.trac.wordpress.org/ticket/39007
return $input;
}
$event = wp_parse_args( $event = wp_parse_args(
self::$events[$filter][$priority], self::$events[ $filter ][ $priority ],
array( array(
'action' => 'start', 'action' => 'start',
'category' => null, 'category' => null,
) )
); );
self::$stopwatch->$event['action']( $event['event'], $event['category'] ); if ( 'stop' === $event['action'] && ! self::$stopwatch->isStarted( $event['event'] ) ) {
return $input;
}
self::$stopwatch->{$event['action']}( $event['event'], $event['category'] );
return $input; return $input;
} }
@@ -114,12 +122,12 @@ class Laps {
* *
* @return string * @return string
*/ */
static function query( $query ) { public static function query( $query ) {
global $wpdb; global $wpdb;
if ( empty( self::$query_starts ) && ! empty( $wpdb->queries ) ) { if ( empty( self::$query_starts ) && ! empty( $wpdb->queries ) ) {
self::$query_starts[count( $wpdb->queries )] = microtime( true ) * 1000; self::$query_starts[ count( $wpdb->queries ) ] = microtime( true ) * 1000;
} else { } else {
self::$query_starts[] = microtime( true ) * 1000; self::$query_starts[] = microtime( true ) * 1000;
} }
@@ -136,7 +144,7 @@ class Laps {
* *
* @return boolean * @return boolean
*/ */
static function pre_http_request( $false, $args, $url ) { public static function pre_http_request( $false, $args, $url ) {
self::$stopwatch->start( $url, 'http' ); self::$stopwatch->start( $url, 'http' );
@@ -154,7 +162,7 @@ class Laps {
* *
* @return mixed * @return mixed
*/ */
static function http_api_debug( $response, $type, $class, $args, $url ) { public static function http_api_debug( $response, $type, $class, $args, $url ) {
self::$stopwatch->stop( $url ); self::$stopwatch->stop( $url );
@@ -162,60 +170,44 @@ class Laps {
} }
/** /**
* When theme is done possibly add theme-specific events. * When theme is done possibly add vendor-specific events.
*/ */
static function after_setup_theme() { public static function after_setup_theme() {
foreach ( array( 'THA', 'Hybrid', 'Genesis', 'Thematic' ) as $theme ) { foreach ( array( 'THA', 'Hybrid', 'Genesis', 'Thematic', 'Yoast' ) as $vendor ) {
$class = "Rarst\\Laps\\{$theme}_Events"; $class = "Rarst\\Laps\\{$vendor}_Events";
/** @var Laps_Events $events */ /** @var Laps_Events $events */
$events = new $class; $events = new $class;
self::add_events( $events->get() ); self::add_events( $events->get() );
} }
} }
static function init() { public static function init() {
add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) ); add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) ); add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
add_action( 'admin_bar_menu', array( __CLASS__, 'admin_bar_menu' ), 100 ); add_action( 'admin_bar_menu', array( __CLASS__, 'admin_bar_menu' ), 100 );
add_action( 'wp_print_footer_scripts', array( __CLASS__, 'print_footer_scripts' ), 11 );
add_action( 'admin_print_footer_scripts', array( __CLASS__, 'print_footer_scripts' ), 11 );
} }
static function enqueue_scripts() { public static function enqueue_scripts() {
wp_register_script( 'laps-tooltip', plugins_url( 'js/tooltip.js', __DIR__ ), array( 'jquery' ), '3.0.2', true ); $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
wp_register_style( 'laps', plugins_url( 'css/laps.css', __DIR__ ) ); wp_register_script( 'laps', plugins_url( "js/laps{$suffix}.js", __DIR__ ), array( 'jquery' ), '3.3.1', true );
wp_register_style( 'laps', plugins_url( "css/laps{$suffix}.css", __DIR__ ) );
if ( is_admin_bar_showing() ) { if ( is_admin_bar_showing() ) {
wp_enqueue_script( 'laps-tooltip' ); wp_enqueue_script( 'laps' );
wp_enqueue_style( 'laps' ); wp_enqueue_style( 'laps' );
} }
} }
static function print_footer_scripts() {
if ( wp_script_is( 'laps-tooltip', 'done' ) ) {
?>
<script type="text/javascript">
jQuery(document).ready(function () {
jQuery(".laps-timeline .event").lapstooltip({
container: '#wpadminbar', placement: 'bottom', html: true, animation: false
// , trigger: 'click'
});
});
</script><?php
}
}
/** /**
* Render interface and add to the toolbar. * Render interface and add to the toolbar.
* *
* @param \WP_Admin_Bar $wp_admin_bar * @param \WP_Admin_Bar $wp_admin_bar
*/ */
static function admin_bar_menu( $wp_admin_bar ) { public static function admin_bar_menu( $wp_admin_bar ) {
if ( ! apply_filters( 'laps_can_see', current_user_can( 'manage_options' ) ) ) { if ( ! apply_filters( 'laps_can_see', current_user_can( 'manage_options' ) ) ) {
return; return;
@@ -226,10 +218,13 @@ class Laps {
$mustache = new \Mustache_Engine( $mustache = new \Mustache_Engine(
array( array(
'loader' => new \Mustache_Loader_FilesystemLoader( dirname( __DIR__ ) . '/views' ), 'loader' => new \Mustache_Loader_FilesystemLoader( dirname( __DIR__ ) . '/views' ),
'cache' => new Mustache_Cache_FrozenCache( dirname( __DIR__ ) . '/views/cache' ),
) )
); );
self::$stopwatch->stop( 'Toolbar' ); if ( self::$stopwatch->isStarted( 'Toolbar' ) ) {
self::$stopwatch->stop( 'Toolbar' );
}
$events = self::$stopwatch->getSectionEvents( '__root__' ); $events = self::$stopwatch->getSectionEvents( '__root__' );
$start = $timestart * 1000; $start = $timestart * 1000;
@@ -245,7 +240,7 @@ class Laps {
$width = round( $duration / $total * 100, 2 ); $width = round( $duration / $total * 100, 2 );
$category = $event->getCategory(); $category = $event->getCategory();
if ( 'http' == $category ) { if ( 'http' === $category ) {
$http_data[] = compact( 'name', 'offset', 'duration', 'width', 'category' ); $http_data[] = compact( 'name', 'offset', 'duration', 'width', 'category' );
continue; continue;
} }
@@ -259,25 +254,31 @@ class Laps {
$last_query_end = 0; $last_query_end = 0;
$last_offset = 0; $last_offset = 0;
$last_duration = 0; $last_duration = 0;
$category = 'query';
if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) { if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
foreach ( $wpdb->queries as $key => $query ) { foreach ( $wpdb->queries as $key => $query ) {
$query_start = isset( self::$query_starts[$key] ) ? self::$query_starts[$key] : $last_query_end; $query_start = isset( self::$query_starts[ $key ] ) ? self::$query_starts[ $key ] : $last_query_end;
list( $sql, $duration, $trace ) = $query; list( $sql, $duration, $trace ) = $query;
$sql = trim( $sql );
$category = 'query-read';
if ( 0 === stripos( $sql, 'INSERT' ) || 0 === stripos( $sql, 'UPDATE' ) ) {
$category = 'query-write';
}
$duration *= 1000; $duration *= 1000;
$last_query_end = $query_start + $duration; $last_query_end = $query_start + $duration;
$offset = round( ( $query_start - $start ) / $total * 100, 2 ); $offset = round( ( $query_start - $start ) / $total * 100, 2 );
// if query is indistinguishably close to previous then stack it // if query is indistinguishably close to previous then stack it
if ( $offset == $last_offset ) { if ( $offset === $last_offset ) {
$key = count( $query_data ) - 1; $key = count( $query_data ) - 1;
$query_data[$key]['sql'] .= '<br />' . $sql; $query_data[ $key ]['sql'] .= '<br />' . $sql;
$last_duration += $duration; $last_duration += $duration;
$width = round( $last_duration / $total * 100, 2 ); $width = round( $last_duration / $total * 100, 2 );
$query_data[$key]['width'] = $width; $query_data[ $key ]['width'] = $width;
continue; continue;
} }
@@ -290,8 +291,6 @@ class Laps {
} }
} }
// !d( self::$query_starts, $wpdb->queries, $query_data );
$html = $mustache->render( $html = $mustache->render(
'laps', 'laps',
array( array(
@@ -303,19 +302,15 @@ class Laps {
) )
); );
$wp_admin_bar->add_node( $wp_admin_bar->add_node( array(
array( 'id' => 'laps',
'id' => 'laps', 'title' => sprintf( 'Lap: %ss', round( $total / 1000, 3 ) ),
'title' => sprintf( 'Lap: %ss', round( $total / 1000, 3 ) ), ) );
)
);
$wp_admin_bar->add_node( $wp_admin_bar->add_node( array(
array( 'id' => 'laps_output',
'id' => 'laps_output', 'parent' => 'laps',
'parent' => 'laps', 'meta' => array( 'html' => $html ),
'meta' => array( 'html' => $html ), ) );
)
);
} }
} }
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace Rarst\Laps;
/**
* Implements read-only filesystem cache
*/
class Mustache_Cache_FrozenCache extends \Mustache_Cache_FilesystemCache {
/**
* Cache and load a compiled Mustache_Template class.
*
* @param string $key
* @param string $value
*
* @return void
*/
public function cache( $key, $value ) {
$this->log(
\Mustache_Logger::WARNING,
'Read only cache file missing, evaluating "{className}" class at runtime',
array( 'className' => $key )
);
eval( '?>' . $value );
}
}
+1 -1
View File
@@ -48,4 +48,4 @@ class THA_Events extends Laps_Events {
return $events; return $events;
} }
} }
+1 -1
View File
@@ -59,4 +59,4 @@ class Thematic_Events extends Laps_Events {
return $events; return $events;
} }
} }
+38
View File
@@ -0,0 +1,38 @@
<?php
namespace Rarst\Laps;
/**
* Events for Yoast plugins
*/
class Yoast_Events extends Laps_Events {
/**
* @return bool
*/
protected function is_applicable() {
return class_exists( 'WPSEO_Frontend' );
}
/**
* @return array
*/
public function get_events() {
$stops = array();
$stops['wpseo_head'][1] = array(
'event' => 'WP SEO head hook',
'category' => 'plugin',
);
$stops['wpseo_head'][100] = array(
'action' => 'stop',
'event' => 'WP SEO head hook',
'category' => 'plugin',
);
return $stops;
}
}
@@ -0,0 +1,292 @@
<?php
class __Mustache_797f2a84b9a5a7b601644494da75d61e extends Mustache_Template
{
private $lambdaHelper;
public function renderInternal(Mustache_Context $context, $indent = '')
{
$this->lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context);
$buffer = '';
$blocksContext = array();
$buffer .= $indent . '<div class="laps-timeline">
';
// 'events' section
$value = $context->find('events');
$buffer .= $this->section940385acb9865793d8943db356869c18($context, $indent, $value);
$buffer .= $indent . '</div>
';
$buffer .= $indent . '
';
// 'savequeries' section
$value = $context->find('savequeries');
$buffer .= $this->sectionB93c1beb6bc5c41326a972381b0dd94a($context, $indent, $value);
$buffer .= $indent . '
';
// 'savehttp' section
$value = $context->find('savehttp');
$buffer .= $this->section238f05e38d8d133266503e545e18de7e($context, $indent, $value);
return $buffer;
}
private function section940385acb9865793d8943db356869c18(Mustache_Context $context, $indent, $value)
{
$buffer = '';
$blocksContext = array();
if (!is_string($value) && is_callable($value)) {
$source = '
<div class="event event-{{category}}" data-toggle="tooltip" title="{{name}} - {{duration}} ms - {{memory}} MB" style="width:{{width}}%; left:{{offset}}%;">
<span class="sr-only">{{name}} - {{duration}} ms - {{memory}} MB</span>
</div>
';
$result = call_user_func($value, $source, $this->lambdaHelper);
if (strpos($result, '{{') === false) {
$buffer .= $result;
} else {
$buffer .= $this->mustache
->loadLambda((string) $result)
->renderInternal($context);
}
} elseif (!empty($value)) {
$values = $this->isIterable($value) ? $value : array($value);
foreach ($values as $value) {
$context->push($value);
$buffer .= $indent . ' <div class="event event-';
$value = $this->resolveValue($context->find('category'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '" data-toggle="tooltip" title="';
$value = $this->resolveValue($context->find('name'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' - ';
$value = $this->resolveValue($context->find('duration'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' ms - ';
$value = $this->resolveValue($context->find('memory'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' MB" style="width:';
$value = $this->resolveValue($context->find('width'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '%; left:';
$value = $this->resolveValue($context->find('offset'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '%;">
';
$buffer .= $indent . ' <span class="sr-only">';
$value = $this->resolveValue($context->find('name'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' - ';
$value = $this->resolveValue($context->find('duration'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' ms - ';
$value = $this->resolveValue($context->find('memory'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' MB</span>
';
$buffer .= $indent . ' </div>
';
$context->pop();
}
}
return $buffer;
}
private function section372053fedd826e7e297c29f607930cbc(Mustache_Context $context, $indent, $value)
{
$buffer = '';
$blocksContext = array();
if (!is_string($value) && is_callable($value)) {
$source = '
<div class="event event-{{category}}" title="{{sql}}" style="width:{{width}}%; left:{{offset}}%;">
<span class="sr-only">{{sql}}</span>
</div>
';
$result = call_user_func($value, $source, $this->lambdaHelper);
if (strpos($result, '{{') === false) {
$buffer .= $result;
} else {
$buffer .= $this->mustache
->loadLambda((string) $result)
->renderInternal($context);
}
} elseif (!empty($value)) {
$values = $this->isIterable($value) ? $value : array($value);
foreach ($values as $value) {
$context->push($value);
$buffer .= $indent . ' <div class="event event-';
$value = $this->resolveValue($context->find('category'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '" title="';
$value = $this->resolveValue($context->find('sql'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '" style="width:';
$value = $this->resolveValue($context->find('width'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '%; left:';
$value = $this->resolveValue($context->find('offset'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '%;">
';
$buffer .= $indent . ' <span class="sr-only">';
$value = $this->resolveValue($context->find('sql'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '</span>
';
$buffer .= $indent . ' </div>
';
$context->pop();
}
}
return $buffer;
}
private function sectionB93c1beb6bc5c41326a972381b0dd94a(Mustache_Context $context, $indent, $value)
{
$buffer = '';
$blocksContext = array();
if (!is_string($value) && is_callable($value)) {
$source = '
<div class="laps-timeline">
{{#queries}}
<div class="event event-{{category}}" title="{{sql}}" style="width:{{width}}%; left:{{offset}}%;">
<span class="sr-only">{{sql}}</span>
</div>
{{/queries}}
</div>
';
$result = call_user_func($value, $source, $this->lambdaHelper);
if (strpos($result, '{{') === false) {
$buffer .= $result;
} else {
$buffer .= $this->mustache
->loadLambda((string) $result)
->renderInternal($context);
}
} elseif (!empty($value)) {
$values = $this->isIterable($value) ? $value : array($value);
foreach ($values as $value) {
$context->push($value);
$buffer .= $indent . '<div class="laps-timeline">
';
// 'queries' section
$value = $context->find('queries');
$buffer .= $this->section372053fedd826e7e297c29f607930cbc($context, $indent, $value);
$buffer .= $indent . '</div>
';
$context->pop();
}
}
return $buffer;
}
private function section26362c0132f6d74333e6154005595603(Mustache_Context $context, $indent, $value)
{
$buffer = '';
$blocksContext = array();
if (!is_string($value) && is_callable($value)) {
$source = '
<div class="event event-{{category}}" title="{{name}} - {{duration}} ms" style="width:{{width}}%; left:{{offset}}%;">
<span class="sr-only">{{name}} - {{duration}} ms</span>
</div>
';
$result = call_user_func($value, $source, $this->lambdaHelper);
if (strpos($result, '{{') === false) {
$buffer .= $result;
} else {
$buffer .= $this->mustache
->loadLambda((string) $result)
->renderInternal($context);
}
} elseif (!empty($value)) {
$values = $this->isIterable($value) ? $value : array($value);
foreach ($values as $value) {
$context->push($value);
$buffer .= $indent . ' <div class="event event-';
$value = $this->resolveValue($context->find('category'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '" title="';
$value = $this->resolveValue($context->find('name'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' - ';
$value = $this->resolveValue($context->find('duration'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' ms" style="width:';
$value = $this->resolveValue($context->find('width'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '%; left:';
$value = $this->resolveValue($context->find('offset'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '%;">
';
$buffer .= $indent . ' <span class="sr-only">';
$value = $this->resolveValue($context->find('name'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' - ';
$value = $this->resolveValue($context->find('duration'), $context);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' ms</span>
';
$buffer .= $indent . ' </div>
';
$context->pop();
}
}
return $buffer;
}
private function section238f05e38d8d133266503e545e18de7e(Mustache_Context $context, $indent, $value)
{
$buffer = '';
$blocksContext = array();
if (!is_string($value) && is_callable($value)) {
$source = '
<div class="laps-timeline">
{{#http}}
<div class="event event-{{category}}" title="{{name}} - {{duration}} ms" style="width:{{width}}%; left:{{offset}}%;">
<span class="sr-only">{{name}} - {{duration}} ms</span>
</div>
{{/http}}
</div>
';
$result = call_user_func($value, $source, $this->lambdaHelper);
if (strpos($result, '{{') === false) {
$buffer .= $result;
} else {
$buffer .= $this->mustache
->loadLambda((string) $result)
->renderInternal($context);
}
} elseif (!empty($value)) {
$values = $this->isIterable($value) ? $value : array($value);
foreach ($values as $value) {
$context->push($value);
$buffer .= $indent . '<div class="laps-timeline">
';
// 'http' section
$value = $context->find('http');
$buffer .= $this->section26362c0132f6d74333e6154005595603($context, $indent, $value);
$buffer .= $indent . '</div>
';
$context->pop();
}
}
return $buffer;
}
}
+9 -3
View File
@@ -1,13 +1,17 @@
<div class="laps-timeline"> <div class="laps-timeline">
{{#events}} {{#events}}
<div class="event event-{{category}}" data-toggle="tooltip" title="{{name}} - {{duration}} ms - {{memory}} MB" style="width:{{width}}%; left:{{offset}}%;"></div> <div class="event event-{{category}}" data-toggle="tooltip" title="{{name}} - {{duration}} ms - {{memory}} MB" style="width:{{width}}%; left:{{offset}}%;">
<span class="sr-only">{{name}} - {{duration}} ms - {{memory}} MB</span>
</div>
{{/events}} {{/events}}
</div> </div>
{{#savequeries}} {{#savequeries}}
<div class="laps-timeline"> <div class="laps-timeline">
{{#queries}} {{#queries}}
<div class="event event-{{category}}" title="{{sql}}" style="width:{{width}}%; left:{{offset}}%;"></div> <div class="event event-{{category}}" title="{{sql}}" style="width:{{width}}%; left:{{offset}}%;">
<span class="sr-only">{{sql}}</span>
</div>
{{/queries}} {{/queries}}
</div> </div>
{{/savequeries}} {{/savequeries}}
@@ -15,7 +19,9 @@
{{#savehttp}} {{#savehttp}}
<div class="laps-timeline"> <div class="laps-timeline">
{{#http}} {{#http}}
<div class="event event-{{category}}" title="{{name}} - {{duration}} ms" style="width:{{width}}%; left:{{offset}}%;"></div> <div class="event event-{{category}}" title="{{name}} - {{duration}} ms" style="width:{{width}}%; left:{{offset}}%;">
<span class="sr-only">{{name}} - {{duration}} ms</span>
</div>
{{/http}} {{/http}}
</div> </div>
{{/savehttp}} {{/savehttp}}