Compare commits

..

18 Commits

Author SHA1 Message Date
Andreas Hocevar
c914ac2a64 Changelog for v6.2.1 2020-02-13 20:52:10 +01:00
Andreas Hocevar
643552f13f Merge pull request #10656 from mike-000/patch-6
Fix for export PDF example compatibility issues, and layer opacity handling.
2020-02-13 20:06:44 +01:00
mike-000
0b893f11d3 Fix IE compatibility. Add opacity handling.
querySelectorAll().forEach() isn't supported by IE.
Add opacity to the vector layer and handle it in the output.
2020-02-13 18:13:07 +00:00
mike-000
f302b5883e Update jspdf version 2020-02-13 18:06:02 +00:00
Andreas Hocevar
8750cb0b1a Merge pull request #10653 from ahocevar/apidoc-nav
More reliable check for module content beyond classes
2020-02-13 14:30:26 +01:00
Andreas Hocevar
32238806a6 Merge pull request #10617 from MoonE/apidoc-performance
Improve apidoc generation performance
2020-02-13 11:03:02 +01:00
Andreas Hocevar
4e1ca0a986 More reliable check for module content beyond classes 2020-02-13 10:41:52 +01:00
Andreas Hocevar
8b6d5eb5c8 Merge pull request #10625 from MoonE/apidoc-cleanup-navigation
Apidoc cleanup navigation html
2020-02-13 10:04:36 +01:00
Andreas Hocevar
1d5f9ae369 Merge pull request #10649 from ahocevar/remove-circular-dependency
Remove circular dependency
2020-02-13 08:35:58 +01:00
Andreas Hocevar
262373a4b5 Remove circular dependency 2020-02-12 20:31:18 +01:00
Andreas Hocevar
8742d8fbc7 Merge pull request #10637 from openlayers/dev-6.2.1
Develop on 6.2.1
2020-02-11 16:41:47 +01:00
Andreas Hocevar
af18045fc8 Develop on 6.2.1 2020-02-11 16:29:51 +01:00
Andreas Hocevar
1d0f0f5205 Merge pull request #10636 from openlayers/release-v6.2.0
Release v6.2.0
2020-02-11 16:23:07 +01:00
Maximilian Krög
300cc282e4 Generate valid html for the apidoc navigation
Only `<li>` can be a direct descendant of `<ul>` tags.
2020-02-10 00:10:05 +01:00
Maximilian Krög
5d922fc53b Cleanup navigation.tmpl and the generated html
- Add a function that is used to generate all four types of member lists.
- Only use one line per list item.
- Don't generate empty `class=""` attributes when item is stable.
- Remove closing `</li>` tag, as is allowed by the html 5 standard.

Overall this reduces the filesize for the generated html pages by ~33%.
2020-02-10 00:09:33 +01:00
Maximilian Krög
c0f058f5cf Variable should be reset on each loop but wasn't
The ancestors variable is always set once the first augmented doclet is found.
The incompleteDoclet variable is also not reset between loops.
2020-02-07 00:08:14 +01:00
Maximilian Krög
2e4f989d7b Store api members as object map instead of array. 2020-02-07 00:08:14 +01:00
Maximilian Krög
0c04293d5f Generate navigation html only once for all pages.
This reduces the time for apidoc generation by ~30%.
2020-02-07 00:08:07 +01:00
15 changed files with 156 additions and 177 deletions

View File

@@ -1,5 +1,9 @@
## Upgrade notes
### v6.2.0
### v6.1.0
### v6.0.0
#### Backwards incompatible changes

13
changelog/v6.2.1.md Normal file
View File

@@ -0,0 +1,13 @@
# 6.2.1
This is a bugfix release which resolves bundler issues due to a circular dependency, and brings a few documentation and example fixes.
## List of all changes
* [#10656](https://github.com/openlayers/openlayers/pull/10656) - Fix for export PDF example compatibility issues, and layer opacity handling. ([@mike-000](https://github.com/mike-000))
* [#10653](https://github.com/openlayers/openlayers/pull/10653) - More reliable check for module content beyond classes ([@ahocevar](https://github.com/ahocevar))
* [#10617](https://github.com/openlayers/openlayers/pull/10617) - Improve apidoc generation performance ([@MoonE](https://github.com/MoonE))
* [#10625](https://github.com/openlayers/openlayers/pull/10625) - Apidoc cleanup navigation html ([@MoonE](https://github.com/MoonE))
* [#10649](https://github.com/openlayers/openlayers/pull/10649) - Remove circular dependency ([@ahocevar](https://github.com/ahocevar))
* [#10637](https://github.com/openlayers/openlayers/pull/10637) - Develop on 6.2.1 ([@openlayers](https://github.com/openlayers))

View File

@@ -21,15 +21,11 @@ exports.defineTags = function(dictionary) {
* from the documentation.
*/
const api = [];
const api = {};
const classes = {};
const types = {};
const modules = {};
function hasApiMembers(doclet) {
return doclet.longname.split('#')[0] == this.longname;
}
function includeAugments(doclet) {
// Make sure that `observables` and `fires` are taken from an already processed `class` doclet.
// This is necessary because JSDoc generates multiple doclets with the same longname.
@@ -116,7 +112,7 @@ exports.handlers = {
const doclet = e.doclet;
if (doclet.stability) {
modules[doclet.longname.split(/[~\.]/).shift()] = true;
api.push(doclet);
api[doclet.longname.split('#')[0]] = true;
}
if (doclet.kind == 'class') {
if (!(doclet.longname in classes)) {
@@ -159,7 +155,7 @@ exports.handlers = {
if (doclet.isEnum || doclet.kind == 'typedef') {
continue;
}
if (doclet.kind == 'class' && api.some(hasApiMembers, doclet)) {
if (doclet.kind == 'class' && doclet.longname in api) {
// Mark undocumented classes with documented members as unexported.
// This is used in ../template/tmpl/container.tmpl to hide the
// constructor from the docs.

View File

@@ -42,62 +42,62 @@ exports.handlers = {
parseComplete: function(e) {
let ancestors, candidate, candidates, doclet, i, j, k, l, key;
let incompleteDoclet, stability, incomplete, incompletes;
let stability, incomplete, incompletes;
const doclets = e.doclets;
for (i = doclets.length - 1; i >= 0; --i) {
doclet = doclets[i];
if (doclet.augments) {
ancestors = [].concat(doclet.augments);
}
incompletes = incompleteByClass[doclet.longname];
if (ancestors && incompletes) {
// collect ancestors from the whole hierarchy
for (j = 0; j < ancestors.length; ++j) {
candidates = lookup[ancestors[j]];
if (candidates) {
for (k = candidates.length - 1; k >= 0; --k) {
candidate = candidates[k];
if (candidate.augments) {
ancestors = ancestors.concat(candidate.augments);
}
if (!doclet.augments || !incompletes) {
continue;
}
ancestors = doclet.augments.slice();
// collect ancestors from the whole hierarchy
for (j = 0; j < ancestors.length; ++j) {
candidates = lookup[ancestors[j]];
if (candidates) {
for (k = candidates.length - 1; k >= 0; --k) {
candidate = candidates[k];
if (candidate.augments) {
Array.prototype.push.apply(ancestors, candidate.augments);
}
}
}
// walk through all inheritDoc members
for (j = incompletes.length - 1; j >= 0; --j) {
incomplete = incompletes[j];
candidates = lookup[doclet.longname + '#' + incomplete];
if (candidates) {
// get the incomplete doclet that needs to be augmented
for (k = candidates.length - 1; k >= 0; --k) {
incompleteDoclet = candidates[k];
if (incompleteDoclet.inheritdoc) {
break;
}
}
// walk through all inheritDoc members
let incompleteDoclet;
for (j = incompletes.length - 1; j >= 0; --j) {
incomplete = incompletes[j];
candidates = lookup[doclet.longname + '#' + incomplete];
if (candidates) {
// get the incomplete doclet that needs to be augmented
for (k = candidates.length - 1; k >= 0; --k) {
incompleteDoclet = candidates[k];
if (incompleteDoclet.inheritdoc) {
break;
}
}
// find the documented ancestor
for (k = ancestors.length - 1; k >= 0; --k) {
candidates = lookup[ancestors[k] + '#' + incomplete];
if (candidates) {
for (l = candidates.length - 1; l >= 0; --l) {
candidate = candidates[l];
if (candidate && !candidate.inheritdoc) {
stability = candidate.stability || incompleteDoclet.stability;
if (stability) {
incompleteDoclet.stability = stability;
for (key in candidate) {
if (candidate.hasOwnProperty(key) &&
keepKeys.indexOf(key) == -1) {
incompleteDoclet[key] = candidate[key];
}
}
// find the documented ancestor
for (k = ancestors.length - 1; k >= 0; --k) {
candidates = lookup[ancestors[k] + '#' + incomplete];
if (candidates) {
for (l = candidates.length - 1; l >= 0; --l) {
candidate = candidates[l];
if (candidate && !candidate.inheritdoc) {
stability = candidate.stability || incompleteDoclet.stability;
if (stability) {
incompleteDoclet.stability = stability;
for (key in candidate) {
if (candidate.hasOwnProperty(key) &&
keepKeys.indexOf(key) == -1) {
incompleteDoclet[key] = candidate[key];
}
// We have found a matching parent doc and applied it so we
// don't want to ignore this doclet anymore.
incompleteDoclet.ignore = false;
// We found a match so we can stop break
break;
}
// We have found a matching parent doc and applied it so we
// don't want to ignore this doclet anymore.
incompleteDoclet.ignore = false;
// We found a match so we can stop break
break;
}
}
}

View File

@@ -274,9 +274,9 @@ function buildNav(members) {
kind: 'event',
memberof: v.longname
});
// only add modules that have more to show than just classes
const numItems = classes.length - 1 + members.length + methods.length + typedefs.length + events.length;
if (!classes.length || (numItems > 0 && numItems !== classes.length)) {
// Only add modules that contain more than just classes with their
// associated Options typedef
if (typedefs.length > classes.length || members.length + methods.length > 0) {
nav.push({
type: 'module',
longname: v.longname,
@@ -477,6 +477,7 @@ exports.publish = function(taffyData, opts, tutorials) {
// index page displays information from package.json and lists files
const files = find({kind: 'file'});
view.navigationHtml = helper.resolveLinks(view.partial('navigation.tmpl'));
generate('Index',
[{kind: 'mainpage', readme: opts.readme, longname: (opts.mainpagetitle) ? opts.mainpagetitle : 'Main Page'}].concat(files),
indexUrl);

View File

@@ -33,7 +33,7 @@ $(function () {
if (value && value.length > 1) {
var regexp = new RegExp(value, 'i');
$el.find('li, .itemMembers').hide();
$el.find('li, .member-list').hide();
$el.find('li').each(function (i, v) {
const $item = $(v);
@@ -41,7 +41,7 @@ $(function () {
if (name && regexp.test(name)) {
const $classEntry = $item.closest('.item');
const $members = $item.closest('.itemMembers');
const $members = $item.closest('.member-list');
// Do the weight thing
$classEntry.removeData('weight');
@@ -60,7 +60,7 @@ $(function () {
.appendTo(".navigation ul.list"); // append again to the list
} else {
$el.find('.item, .itemMembers').show();
$el.find('.item, .member-list').show();
}
$el.find('.list').scrollTop(0);
@@ -68,7 +68,7 @@ $(function () {
// Toggle when click an item element
$('.navigation').on('click', '.toggle', function (e) {
$(this).parent().parent().find('.itemMembers').toggle();
$(this).parent().parent().find('.member-list').toggle();
});
// Show an item related a current documentation automatically
@@ -84,7 +84,7 @@ $(function () {
.remove()
.prependTo('.navigation .list')
.show()
.find('.itemMembers')
.find('.member-list')
.show();
}

View File

@@ -183,7 +183,7 @@ li {
padding-left: 8px;
margin-top: 2px;
}
.navigation li.item .itemMembers {
.navigation li.item .member-list {
display: none;
padding-left: 8px;
}

View File

@@ -92,7 +92,7 @@ var version = obj.packageInfo.version;
</div>
<div id="wrap" class="clearfix">
<?js= this.partial('navigation.tmpl', this) ?>
<?js= this.navigationHtml ?>
<div class="main">
<h1 class="page-title" data-filename="<?js= filename ?>"><?js= title ?></h1>
<div id="latest-check" class="alert alert-warning alert-dismissible" role="alert" style="display:none">

View File

@@ -1,95 +1,59 @@
<?js
var self = this;
function toShortName(name) {
return name.indexOf('module:') === 0 ? name.split('/').pop() : name;
}
function getItemCssClass(type) {
if (type === 'module') {
return 'glyphicon-plus';
} else if (type === 'class') {
return 'glyphicon-chevron-right';
}
return '';
}
const printList = v => { ?>
<li data-name="<?js= v.longname ?>"><?js
}
const printListWithStability = v => {
const cls = v.stability && v.stability !== 'stable' ? ' class="unstable"' : ''; ?>
<li data-name="<?js= v.longname ?>"<?js= cls ?>><?js
}
function listContent(item, title, listItemPrinter) {
const type = title.toLowerCase();
if (item[type] && item[type].length) { ?>
<div class="member-list">
<span class="subtitle"><?js= title ?></span>
<ul><?js
item[type].forEach(function (v) {
listItemPrinter(v); ?><?js= self.linkto(v.longname, toShortName(v.name)) ?><?js
}); ?>
</ul>
</div><?js
}
}
?>
<div class="navigation">
<div class="search">
<input id="search" type="text" class="form-control input-sm" placeholder="Search Documentation">
</div>
<ul class="list">
<?js
this.nav.forEach(function (item) {
?>
<ul class="list"><?js
this.nav.forEach(function (item) { ?>
<li class="item" data-name="<?js= item.longname ?>" data-shortname="<?js= item.name.toLowerCase() ?>">
<span class="title">
<?js if (item.type === 'module') { ?>
<span class="glyphicon glyphicon-plus toggle"></span>
<?js } else if (item.type === 'class') { ?>
<span class="glyphicon glyphicon-chevron-right toggle"></span>
<?js } ?>
<span class="glyphicon <?js= getItemCssClass(item.type) ?> toggle"></span>
<?js= self.linkto(item.longname, item.prettyname) ?>
<?js if (item.type === 'namespace' &&
(item.members.length + item.typedefs.length + item.methods.length +
item.events.length > 0)) { ?>
<?js } ?>
</span>
<ul class="members itemMembers">
<?js
if (item.members.length) {
?>
<span class="subtitle">Members</span>
<?js
item.members.forEach(function (v) {
?>
<li data-name="<?js= v.longname ?>"><?js= self.linkto(v.longname, toShortName(v.name)) ?></li>
<?js
});
}
?>
</ul>
<ul class="typedefs itemMembers">
<?js
if (item.typedefs.length) {
?>
<span class="subtitle">Typedefs</span>
<?js
item.typedefs.forEach(function (v) {
?>
<li data-name="<?js= v.longname ?>" class="<?js= (v.stability && v.stability !== 'stable') ? 'unstable' : ''?>">
<?js= self.linkto(v.longname, toShortName(v.name)) ?>
</li>
<?js
});
}
?>
</ul>
<ul class="methods itemMembers">
<?js
if (item.methods.length) {
?>
<span class="subtitle">Methods</span>
<?js
item.methods.forEach(function (v) {
?>
<li data-name="<?js= v.longname ?>" class="<?js= (v.stability && v.stability !== 'stable') ? 'unstable' : ''?>">
<?js= self.linkto(v.longname, toShortName(v.name)) ?>
</li>
<?js
});
}
?>
</ul>
<ul class="fires itemMembers">
<?js
if (item.fires && item.fires.length) {
?>
<span class="subtitle">Fires</span>
<?js
item.fires.forEach(function (v) {
v = self.find({longname: v})[0] || {longname: v, name: v.split(/#?event:/)[1]};
?>
<li data-name="<?js= v.longname ?>" class="<?js= (v.stability && v.stability != 'stable') ? 'unstable' : '' ?>">
<?js= self.linkto(v.longname, toShortName(v.name)) ?>
</li>
<?js
});
}
?>
</ul>
</li>
<?js }); ?>
</span><?js
listContent(item, 'Members', printList);
listContent(item, 'Typedefs', printListWithStability);
listContent(item, 'Methods', printListWithStability);
if (item.fires) {
const fires = item.fires.map(v => self.find({longname: v})[0] || {longname: v, name: v.split(/#?event:/)[1]});
listContent({fires: fires}, 'Fires', printListWithStability)
}
}); ?>
</ul>
</div>

View File

@@ -6,7 +6,7 @@ docs: >
Example of exporting a map as a PDF using the <a href="https://github.com/MrRio/jsPDF" target="_blank">jsPDF</a> library.
tags: "export, pdf, openstreetmap"
resources:
- https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.2.61/jspdf.min.js
- https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js
---
<div class="row-fluid">
<div class="span12">

View File

@@ -18,7 +18,8 @@ feature.getGeometry().transform('EPSG:4326', 'EPSG:3857');
const vector = new VectorLayer({
source: new VectorSource({
features: [feature]
})
}),
opacity: 0.5
});
@@ -62,8 +63,10 @@ exportButton.addEventListener('click', function() {
mapCanvas.width = width;
mapCanvas.height = height;
const mapContext = mapCanvas.getContext('2d');
document.querySelectorAll('.ol-layer canvas').forEach(function(canvas) {
Array.prototype.forEach.call(document.querySelectorAll('.ol-layer canvas'), function(canvas) {
if (canvas.width > 0) {
const opacity = canvas.parentNode.style.opacity;
mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
const transform = canvas.style.transform;
// Get the transform parameters from the style's transform matrix
const matrix = transform.match(/^matrix\(([^\(]*)\)$/)[1].split(',').map(Number);

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "ol",
"version": "6.2.0",
"version": "6.2.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "ol",
"version": "6.2.0",
"version": "6.2.1",
"description": "OpenLayers mapping library",
"keywords": [
"map",

View File

@@ -4,7 +4,6 @@
import {getFontParameters} from '../css.js';
import {createCanvasContext2D} from '../dom.js';
import {clear} from '../obj.js';
import {executeLabelInstructions} from './canvas/Executor.js';
import BaseObject from '../Object.js';
import EventTarget from '../events/Target.js';
@@ -14,6 +13,12 @@ import EventTarget from '../events/Target.js';
* @property {import("../colorlike.js").ColorLike} fillStyle
*/
/**
* @typedef Label
* @property {number} width
* @property {number} height
* @property {Array<string|number>} contextInstructions
*/
/**
* @typedef {Object} FillStrokeState
@@ -386,7 +391,7 @@ export function rotateAtOffset(context, rotation, offsetX, offsetY) {
* @param {CanvasRenderingContext2D} context Context.
* @param {import("../transform.js").Transform|null} transform Transform.
* @param {number} opacity Opacity.
* @param {import("./canvas/Executor.js").Label|HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} labelOrImage Label.
* @param {Label|HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} labelOrImage Label.
* @param {number} originX Origin X.
* @param {number} originY Origin Y.
* @param {number} w Width.
@@ -407,7 +412,7 @@ export function drawImageOrLabel(context,
// label
context.translate(x, y);
context.scale(scale, scale);
executeLabelInstructions(/** @type {import("./canvas/Executor.js").Label} */ (labelOrImage), context);
executeLabelInstructions(/** @type {Label} */ (labelOrImage), context);
} else {
// image
context.drawImage(/** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */ (labelOrImage), originX, originY, w, h, x, y, w * scale, h * scale);
@@ -415,3 +420,18 @@ export function drawImageOrLabel(context,
context.restore();
}
/**
* @param {Label} label Label.
* @param {CanvasRenderingContext2D} context Context.
*/
function executeLabelInstructions(label, context) {
const contextInstructions = label.contextInstructions;
for (let i = 0, ii = contextInstructions.length; i < ii; i += 2) {
if (Array.isArray(contextInstructions[i + 1])) {
CanvasRenderingContext2D.prototype[contextInstructions[i]].apply(context, contextInstructions[i + 1]);
} else {
context[contextInstructions[i]] = contextInstructions[i + 1];
}
}
}

View File

@@ -30,28 +30,6 @@ import RBush from 'rbush/rbush.js';
* @property {!Object<string, import("../canvas.js").StrokeState>} strokeStates The stroke states (decluttering).
*/
/**
* @typedef Label
* @property {number} width
* @property {number} height
* @property {Array<string|number>} contextInstructions
*/
/**
* @param {Label} label Label.
* @param {CanvasRenderingContext2D} context Context.
*/
export function executeLabelInstructions(label, context) {
const contextInstructions = label.contextInstructions;
for (let i = 0, ii = contextInstructions.length; i < ii; i += 2) {
if (Array.isArray(contextInstructions[i + 1])) {
CanvasRenderingContext2D.prototype[contextInstructions[i]].apply(context, contextInstructions[i + 1]);
} else {
context[contextInstructions[i]] = contextInstructions[i + 1];
}
}
}
/**
* @type {import("../../extent.js").Extent}
*/
@@ -176,7 +154,7 @@ class Executor {
/**
* @private
* @type {Object<string, Label>}
* @type {Object<string, import("../canvas.js").Label>}
*/
this.labels_ = {};
}
@@ -186,7 +164,7 @@ class Executor {
* @param {string} textKey Text style key.
* @param {string} fillKey Fill style key.
* @param {string} strokeKey Stroke style key.
* @return {Label} Label.
* @return {import("../canvas.js").Label} Label.
*/
createLabel(text, textKey, fillKey, strokeKey) {
const key = text + textKey + fillKey + strokeKey;
@@ -209,7 +187,7 @@ class Executor {
const height = lineHeight * numLines;
const renderWidth = width + strokeWidth;
const contextInstructions = [];
/** @type {Label} */
/** @type {import("../canvas.js").Label} */
const label = {
// make canvas 2 pixels wider to account for italic text width measurement errors
width: Math.ceil((renderWidth + 2) * scale),
@@ -283,7 +261,7 @@ class Executor {
* @param {CanvasRenderingContext2D} context Context.
* @param {number} x X.
* @param {number} y Y.
* @param {Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} imageOrLabel Image.
* @param {import("../canvas.js").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} imageOrLabel Image.
* @param {number} anchorX Anchor X.
* @param {number} anchorY Anchor Y.
* @param {import("../canvas.js").DeclutterGroup} declutterGroup Declutter group.
@@ -488,7 +466,7 @@ class Executor {
* @param {string} textKey The key of the text state.
* @param {string} strokeKey The key for the stroke state.
* @param {string} fillKey The key for the fill state.
* @return {{label: Label, anchorX: number, anchorY: number}} The text image and its anchor.
* @return {{label: import("../canvas.js").Label, anchorX: number, anchorY: number}} The text image and its anchor.
*/
drawLabelWithPointPlacement_(text, textKey, strokeKey, fillKey) {
const textState = this.textStates[textKey];