summaryrefslogtreecommitdiffstats
path: root/dom/base/ViewportMetaData.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/ViewportMetaData.cpp')
-rw-r--r--dom/base/ViewportMetaData.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/dom/base/ViewportMetaData.cpp b/dom/base/ViewportMetaData.cpp
new file mode 100644
index 0000000000..2646621629
--- /dev/null
+++ b/dom/base/ViewportMetaData.cpp
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsContentUtils.h"
+#include "nsCRT.h"
+#include "ViewportMetaData.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+/*
+ * Helper function for ViewportMetaData::ProcessViewportInfo.
+ *
+ * Handles a single key=value pair. If it corresponds to a valid viewport
+ * attribute, add it to the document header data. No validation is done on the
+ * value itself (this is done at display time).
+ */
+static void ProcessViewportToken(ViewportMetaData& aData,
+ const nsAString& token) {
+ /* Iterators. */
+ nsAString::const_iterator tip, tail, end;
+ token.BeginReading(tip);
+ tail = tip;
+ token.EndReading(end);
+
+ /* Move tip to the '='. */
+ while ((tip != end) && (*tip != '=')) {
+ ++tip;
+ }
+
+ /* If we didn't find an '=', punt. */
+ if (tip == end) {
+ return;
+ }
+
+ /* Extract the key and value. */
+ const nsAString& key = nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(
+ Substring(tail, tip), true);
+ const nsAString& value = nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(
+ Substring(++tip, end), true);
+
+ /* Check for known keys. If we find a match, insert the appropriate
+ * information into the document header. */
+ RefPtr<nsAtom> key_atom = NS_Atomize(key);
+ if (key_atom == nsGkAtoms::height) {
+ aData.mHeight.Assign(value);
+ } else if (key_atom == nsGkAtoms::width) {
+ aData.mWidth.Assign(value);
+ } else if (key_atom == nsGkAtoms::initial_scale) {
+ aData.mInitialScale.Assign(value);
+ } else if (key_atom == nsGkAtoms::minimum_scale) {
+ aData.mMinimumScale.Assign(value);
+ } else if (key_atom == nsGkAtoms::maximum_scale) {
+ aData.mMaximumScale.Assign(value);
+ } else if (key_atom == nsGkAtoms::user_scalable) {
+ aData.mUserScalable.Assign(value);
+ } else if (key_atom == nsGkAtoms::viewport_fit) {
+ aData.mViewportFit.Assign(value);
+ }
+}
+
+#define IS_SEPARATOR(c) \
+ (((c) == '=') || ((c) == ',') || ((c) == ';') || ((c) == '\t') || \
+ ((c) == '\n') || ((c) == '\r'))
+
+ViewportMetaData::ViewportMetaData(const nsAString& aViewportInfo) {
+ /* Iterators. */
+ nsAString::const_iterator tip, tail, end;
+ aViewportInfo.BeginReading(tip);
+ tail = tip;
+ aViewportInfo.EndReading(end);
+
+ /* Read the tip to the first non-separator character. */
+ while ((tip != end) && (IS_SEPARATOR(*tip) || nsCRT::IsAsciiSpace(*tip))) {
+ ++tip;
+ }
+
+ /* Read through and find tokens separated by separators. */
+ while (tip != end) {
+ /* Synchronize tip and tail. */
+ tail = tip;
+
+ /* Advance tip past non-separator characters. */
+ while ((tip != end) && !IS_SEPARATOR(*tip)) {
+ ++tip;
+ }
+
+ /* Allow white spaces that surround the '=' character */
+ if ((tip != end) && (*tip == '=')) {
+ ++tip;
+
+ while ((tip != end) && nsCRT::IsAsciiSpace(*tip)) {
+ ++tip;
+ }
+
+ while ((tip != end) &&
+ !(IS_SEPARATOR(*tip) || nsCRT::IsAsciiSpace(*tip))) {
+ ++tip;
+ }
+ }
+
+ /* Our token consists of the characters between tail and tip. */
+ ProcessViewportToken(*this, Substring(tail, tip));
+
+ /* Skip separators. */
+ while ((tip != end) && (IS_SEPARATOR(*tip) || nsCRT::IsAsciiSpace(*tip))) {
+ ++tip;
+ }
+ }
+}
+
+#undef IS_SEPARATOR